10b57cec5SDimitry Andric //===- FastISel.cpp - Implementation of the FastISel class ----------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file contains the implementation of the FastISel class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric // "Fast" instruction selection is designed to emit very poor code quickly. 120b57cec5SDimitry Andric // Also, it is not designed to be able to do much lowering, so most illegal 130b57cec5SDimitry Andric // types (e.g. i64 on 32-bit targets) and operations are not supported. It is 140b57cec5SDimitry Andric // also not intended to be able to do much optimization, except in a few cases 150b57cec5SDimitry Andric // where doing optimizations reduces overall compile time. For example, folding 160b57cec5SDimitry Andric // constants into immediate fields is often done, because it's cheap and it 170b57cec5SDimitry Andric // reduces the number of instructions later phases have to examine. 180b57cec5SDimitry Andric // 190b57cec5SDimitry Andric // "Fast" instruction selection is able to fail gracefully and transfer 200b57cec5SDimitry Andric // control to the SelectionDAG selector for operations that it doesn't 210b57cec5SDimitry Andric // support. In many cases, this allows us to avoid duplicating a lot of 220b57cec5SDimitry Andric // the complicated lowering logic that SelectionDAG currently has. 230b57cec5SDimitry Andric // 240b57cec5SDimitry Andric // The intended use for "fast" instruction selection is "-O0" mode 250b57cec5SDimitry Andric // compilation, where the quality of the generated code is irrelevant when 260b57cec5SDimitry Andric // weighed against the speed at which the code can be generated. Also, 270b57cec5SDimitry Andric // at -O0, the LLVM optimizers are not running, and this makes the 280b57cec5SDimitry Andric // compile time of codegen a much higher portion of the overall compile 290b57cec5SDimitry Andric // time. Despite its limitations, "fast" instruction selection is able to 300b57cec5SDimitry Andric // handle enough code on its own to provide noticeable overall speedups 310b57cec5SDimitry Andric // in -O0 compiles. 320b57cec5SDimitry Andric // 330b57cec5SDimitry Andric // Basic operations are supported in a target-independent way, by reading 340b57cec5SDimitry Andric // the same instruction descriptions that the SelectionDAG selector reads, 350b57cec5SDimitry Andric // and identifying simple arithmetic operations that can be directly selected 360b57cec5SDimitry Andric // from simple operators. More complicated operations currently require 370b57cec5SDimitry Andric // target-specific code. 380b57cec5SDimitry Andric // 390b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric #include "llvm/CodeGen/FastISel.h" 420b57cec5SDimitry Andric #include "llvm/ADT/APFloat.h" 430b57cec5SDimitry Andric #include "llvm/ADT/APSInt.h" 440b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 450b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 460b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 470b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 480b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h" 490b57cec5SDimitry Andric #include "llvm/Analysis/BranchProbabilityInfo.h" 500b57cec5SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h" 510b57cec5SDimitry Andric #include "llvm/CodeGen/Analysis.h" 520b57cec5SDimitry Andric #include "llvm/CodeGen/FunctionLoweringInfo.h" 530b57cec5SDimitry Andric #include "llvm/CodeGen/ISDOpcodes.h" 540b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 550b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 560b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 570b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 580b57cec5SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h" 590b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 600b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 610b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 620b57cec5SDimitry Andric #include "llvm/CodeGen/StackMaps.h" 630b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 640b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h" 650b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 660b57cec5SDimitry Andric #include "llvm/CodeGen/ValueTypes.h" 670fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/MachineValueType.h" 680b57cec5SDimitry Andric #include "llvm/IR/Argument.h" 690b57cec5SDimitry Andric #include "llvm/IR/Attributes.h" 700b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h" 710b57cec5SDimitry Andric #include "llvm/IR/CallingConv.h" 720b57cec5SDimitry Andric #include "llvm/IR/Constant.h" 730b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 740b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 750b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h" 760b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 77349cc55cSDimitry Andric #include "llvm/IR/DiagnosticInfo.h" 780b57cec5SDimitry Andric #include "llvm/IR/Function.h" 790b57cec5SDimitry Andric #include "llvm/IR/GetElementPtrTypeIterator.h" 800b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h" 810b57cec5SDimitry Andric #include "llvm/IR/InlineAsm.h" 820b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h" 830b57cec5SDimitry Andric #include "llvm/IR/Instruction.h" 840b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 850b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h" 860b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h" 870b57cec5SDimitry Andric #include "llvm/IR/Mangler.h" 880b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 890b57cec5SDimitry Andric #include "llvm/IR/Operator.h" 900b57cec5SDimitry Andric #include "llvm/IR/PatternMatch.h" 910b57cec5SDimitry Andric #include "llvm/IR/Type.h" 920b57cec5SDimitry Andric #include "llvm/IR/User.h" 930b57cec5SDimitry Andric #include "llvm/IR/Value.h" 940b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 950b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h" 960b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 970b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 980b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 990b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 1000b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 1010b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 1020b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h" 1030b57cec5SDimitry Andric #include <algorithm> 1040b57cec5SDimitry Andric #include <cassert> 1050b57cec5SDimitry Andric #include <cstdint> 1060b57cec5SDimitry Andric #include <iterator> 107bdd1243dSDimitry Andric #include <optional> 1080b57cec5SDimitry Andric #include <utility> 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric using namespace llvm; 1110b57cec5SDimitry Andric using namespace PatternMatch; 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric #define DEBUG_TYPE "isel" 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric STATISTIC(NumFastIselSuccessIndependent, "Number of insts selected by " 1160b57cec5SDimitry Andric "target-independent selector"); 1170b57cec5SDimitry Andric STATISTIC(NumFastIselSuccessTarget, "Number of insts selected by " 1180b57cec5SDimitry Andric "target-specific selector"); 1190b57cec5SDimitry Andric STATISTIC(NumFastIselDead, "Number of dead insts removed on failure"); 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric /// Set the current block to which generated machine instructions will be 1220b57cec5SDimitry Andric /// appended. 1230b57cec5SDimitry Andric void FastISel::startNewBlock() { 1240b57cec5SDimitry Andric assert(LocalValueMap.empty() && 1250b57cec5SDimitry Andric "local values should be cleared after finishing a BB"); 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric // Instructions are appended to FuncInfo.MBB. If the basic block already 1280b57cec5SDimitry Andric // contains labels or copies, use the last instruction as the last local 1290b57cec5SDimitry Andric // value. 1300b57cec5SDimitry Andric EmitStartPt = nullptr; 1310b57cec5SDimitry Andric if (!FuncInfo.MBB->empty()) 1320b57cec5SDimitry Andric EmitStartPt = &FuncInfo.MBB->back(); 1330b57cec5SDimitry Andric LastLocalValue = EmitStartPt; 1340b57cec5SDimitry Andric } 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric void FastISel::finishBasicBlock() { flushLocalValueMap(); } 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric bool FastISel::lowerArguments() { 1390b57cec5SDimitry Andric if (!FuncInfo.CanLowerReturn) 1400b57cec5SDimitry Andric // Fallback to SDISel argument lowering code to deal with sret pointer 1410b57cec5SDimitry Andric // parameter. 1420b57cec5SDimitry Andric return false; 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric if (!fastLowerArguments()) 1450b57cec5SDimitry Andric return false; 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric // Enter arguments into ValueMap for uses in non-entry BBs. 1480b57cec5SDimitry Andric for (Function::const_arg_iterator I = FuncInfo.Fn->arg_begin(), 1490b57cec5SDimitry Andric E = FuncInfo.Fn->arg_end(); 1500b57cec5SDimitry Andric I != E; ++I) { 1515ffd83dbSDimitry Andric DenseMap<const Value *, Register>::iterator VI = LocalValueMap.find(&*I); 1520b57cec5SDimitry Andric assert(VI != LocalValueMap.end() && "Missed an argument?"); 1530b57cec5SDimitry Andric FuncInfo.ValueMap[&*I] = VI->second; 1540b57cec5SDimitry Andric } 1550b57cec5SDimitry Andric return true; 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric /// Return the defined register if this instruction defines exactly one 1590b57cec5SDimitry Andric /// virtual register and uses no other virtual registers. Otherwise return 0. 160e8d8bef9SDimitry Andric static Register findLocalRegDef(MachineInstr &MI) { 1615ffd83dbSDimitry Andric Register RegDef; 1620b57cec5SDimitry Andric for (const MachineOperand &MO : MI.operands()) { 1630b57cec5SDimitry Andric if (!MO.isReg()) 1640b57cec5SDimitry Andric continue; 1650b57cec5SDimitry Andric if (MO.isDef()) { 1660b57cec5SDimitry Andric if (RegDef) 167e8d8bef9SDimitry Andric return Register(); 1680b57cec5SDimitry Andric RegDef = MO.getReg(); 1695ffd83dbSDimitry Andric } else if (MO.getReg().isVirtual()) { 170e8d8bef9SDimitry Andric // This is another use of a vreg. Don't delete it. 1715ffd83dbSDimitry Andric return Register(); 1720b57cec5SDimitry Andric } 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric return RegDef; 1750b57cec5SDimitry Andric } 1760b57cec5SDimitry Andric 1775ffd83dbSDimitry Andric static bool isRegUsedByPhiNodes(Register DefReg, 1780b57cec5SDimitry Andric FunctionLoweringInfo &FuncInfo) { 1790b57cec5SDimitry Andric for (auto &P : FuncInfo.PHINodesToUpdate) 1800b57cec5SDimitry Andric if (P.second == DefReg) 1810b57cec5SDimitry Andric return true; 1820b57cec5SDimitry Andric return false; 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric 185e8d8bef9SDimitry Andric void FastISel::flushLocalValueMap() { 186e8d8bef9SDimitry Andric // If FastISel bails out, it could leave local value instructions behind 187e8d8bef9SDimitry Andric // that aren't used for anything. Detect and erase those. 188e8d8bef9SDimitry Andric if (LastLocalValue != EmitStartPt) { 189e8d8bef9SDimitry Andric // Save the first instruction after local values, for later. 190e8d8bef9SDimitry Andric MachineBasicBlock::iterator FirstNonValue(LastLocalValue); 191e8d8bef9SDimitry Andric ++FirstNonValue; 192d65cd7a5SDimitry Andric 193e8d8bef9SDimitry Andric MachineBasicBlock::reverse_iterator RE = 194e8d8bef9SDimitry Andric EmitStartPt ? MachineBasicBlock::reverse_iterator(EmitStartPt) 195e8d8bef9SDimitry Andric : FuncInfo.MBB->rend(); 196e8d8bef9SDimitry Andric MachineBasicBlock::reverse_iterator RI(LastLocalValue); 197349cc55cSDimitry Andric for (MachineInstr &LocalMI : 198349cc55cSDimitry Andric llvm::make_early_inc_range(llvm::make_range(RI, RE))) { 199e8d8bef9SDimitry Andric Register DefReg = findLocalRegDef(LocalMI); 200e8d8bef9SDimitry Andric if (!DefReg) 201e8d8bef9SDimitry Andric continue; 2020b57cec5SDimitry Andric if (FuncInfo.RegsWithFixups.count(DefReg)) 203e8d8bef9SDimitry Andric continue; 2040b57cec5SDimitry Andric bool UsedByPHI = isRegUsedByPhiNodes(DefReg, FuncInfo); 2050b57cec5SDimitry Andric if (!UsedByPHI && MRI.use_nodbg_empty(DefReg)) { 2060b57cec5SDimitry Andric if (EmitStartPt == &LocalMI) 2070b57cec5SDimitry Andric EmitStartPt = EmitStartPt->getPrevNode(); 2080b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "removing dead local value materialization" 2090b57cec5SDimitry Andric << LocalMI); 2100b57cec5SDimitry Andric LocalMI.eraseFromParent(); 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric } 2130b57cec5SDimitry Andric 214e8d8bef9SDimitry Andric if (FirstNonValue != FuncInfo.MBB->end()) { 215e8d8bef9SDimitry Andric // See if there are any local value instructions left. If so, we want to 216e8d8bef9SDimitry Andric // make sure the first one has a debug location; if it doesn't, use the 217e8d8bef9SDimitry Andric // first non-value instruction's debug location. 218e8d8bef9SDimitry Andric 219e8d8bef9SDimitry Andric // If EmitStartPt is non-null, this block had copies at the top before 220e8d8bef9SDimitry Andric // FastISel started doing anything; it points to the last one, so the 221e8d8bef9SDimitry Andric // first local value instruction is the one after EmitStartPt. 222e8d8bef9SDimitry Andric // If EmitStartPt is null, the first local value instruction is at the 223e8d8bef9SDimitry Andric // top of the block. 224e8d8bef9SDimitry Andric MachineBasicBlock::iterator FirstLocalValue = 225e8d8bef9SDimitry Andric EmitStartPt ? ++MachineBasicBlock::iterator(EmitStartPt) 226e8d8bef9SDimitry Andric : FuncInfo.MBB->begin(); 227e8d8bef9SDimitry Andric if (FirstLocalValue != FirstNonValue && !FirstLocalValue->getDebugLoc()) 228e8d8bef9SDimitry Andric FirstLocalValue->setDebugLoc(FirstNonValue->getDebugLoc()); 229e8d8bef9SDimitry Andric } 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric 232e8d8bef9SDimitry Andric LocalValueMap.clear(); 233e8d8bef9SDimitry Andric LastLocalValue = EmitStartPt; 234e8d8bef9SDimitry Andric recomputeInsertPt(); 235e8d8bef9SDimitry Andric SavedInsertPt = FuncInfo.InsertPt; 2360b57cec5SDimitry Andric } 2370b57cec5SDimitry Andric 2385ffd83dbSDimitry Andric Register FastISel::getRegForValue(const Value *V) { 2390b57cec5SDimitry Andric EVT RealVT = TLI.getValueType(DL, V->getType(), /*AllowUnknown=*/true); 2400b57cec5SDimitry Andric // Don't handle non-simple values in FastISel. 2410b57cec5SDimitry Andric if (!RealVT.isSimple()) 2425ffd83dbSDimitry Andric return Register(); 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric // Ignore illegal types. We must do this before looking up the value 2450b57cec5SDimitry Andric // in ValueMap because Arguments are given virtual registers regardless 2460b57cec5SDimitry Andric // of whether FastISel can handle them. 2470b57cec5SDimitry Andric MVT VT = RealVT.getSimpleVT(); 2480b57cec5SDimitry Andric if (!TLI.isTypeLegal(VT)) { 2490b57cec5SDimitry Andric // Handle integer promotions, though, because they're common and easy. 2500b57cec5SDimitry Andric if (VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16) 2510b57cec5SDimitry Andric VT = TLI.getTypeToTransformTo(V->getContext(), VT).getSimpleVT(); 2520b57cec5SDimitry Andric else 2535ffd83dbSDimitry Andric return Register(); 2540b57cec5SDimitry Andric } 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric // Look up the value to see if we already have a register for it. 2575ffd83dbSDimitry Andric Register Reg = lookUpRegForValue(V); 2580b57cec5SDimitry Andric if (Reg) 2590b57cec5SDimitry Andric return Reg; 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric // In bottom-up mode, just create the virtual register which will be used 2620b57cec5SDimitry Andric // to hold the value. It will be materialized later. 2630b57cec5SDimitry Andric if (isa<Instruction>(V) && 2640b57cec5SDimitry Andric (!isa<AllocaInst>(V) || 2650b57cec5SDimitry Andric !FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(V)))) 2660b57cec5SDimitry Andric return FuncInfo.InitializeRegForValue(V); 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric SavePoint SaveInsertPt = enterLocalValueArea(); 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric // Materialize the value in a register. Emit any instructions in the 2710b57cec5SDimitry Andric // local value area. 2720b57cec5SDimitry Andric Reg = materializeRegForValue(V, VT); 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric leaveLocalValueArea(SaveInsertPt); 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric return Reg; 2770b57cec5SDimitry Andric } 2780b57cec5SDimitry Andric 2795ffd83dbSDimitry Andric Register FastISel::materializeConstant(const Value *V, MVT VT) { 2805ffd83dbSDimitry Andric Register Reg; 2810b57cec5SDimitry Andric if (const auto *CI = dyn_cast<ConstantInt>(V)) { 2820b57cec5SDimitry Andric if (CI->getValue().getActiveBits() <= 64) 2830b57cec5SDimitry Andric Reg = fastEmit_i(VT, VT, ISD::Constant, CI->getZExtValue()); 2840b57cec5SDimitry Andric } else if (isa<AllocaInst>(V)) 2850b57cec5SDimitry Andric Reg = fastMaterializeAlloca(cast<AllocaInst>(V)); 2860b57cec5SDimitry Andric else if (isa<ConstantPointerNull>(V)) 2870b57cec5SDimitry Andric // Translate this as an integer zero so that it can be 2880b57cec5SDimitry Andric // local-CSE'd with actual integer zeros. 289480093f4SDimitry Andric Reg = 290480093f4SDimitry Andric getRegForValue(Constant::getNullValue(DL.getIntPtrType(V->getType()))); 2910b57cec5SDimitry Andric else if (const auto *CF = dyn_cast<ConstantFP>(V)) { 2920b57cec5SDimitry Andric if (CF->isNullValue()) 2930b57cec5SDimitry Andric Reg = fastMaterializeFloatZero(CF); 2940b57cec5SDimitry Andric else 2950b57cec5SDimitry Andric // Try to emit the constant directly. 2960b57cec5SDimitry Andric Reg = fastEmit_f(VT, VT, ISD::ConstantFP, CF); 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric if (!Reg) { 2990b57cec5SDimitry Andric // Try to emit the constant by using an integer constant with a cast. 3000b57cec5SDimitry Andric const APFloat &Flt = CF->getValueAPF(); 3010b57cec5SDimitry Andric EVT IntVT = TLI.getPointerTy(DL); 3020b57cec5SDimitry Andric uint32_t IntBitWidth = IntVT.getSizeInBits(); 3030b57cec5SDimitry Andric APSInt SIntVal(IntBitWidth, /*isUnsigned=*/false); 3040b57cec5SDimitry Andric bool isExact; 3050b57cec5SDimitry Andric (void)Flt.convertToInteger(SIntVal, APFloat::rmTowardZero, &isExact); 3060b57cec5SDimitry Andric if (isExact) { 3075ffd83dbSDimitry Andric Register IntegerReg = 3080b57cec5SDimitry Andric getRegForValue(ConstantInt::get(V->getContext(), SIntVal)); 3095ffd83dbSDimitry Andric if (IntegerReg) 310fe6060f1SDimitry Andric Reg = fastEmit_r(IntVT.getSimpleVT(), VT, ISD::SINT_TO_FP, 311fe6060f1SDimitry Andric IntegerReg); 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric } 3140b57cec5SDimitry Andric } else if (const auto *Op = dyn_cast<Operator>(V)) { 3150b57cec5SDimitry Andric if (!selectOperator(Op, Op->getOpcode())) 3160b57cec5SDimitry Andric if (!isa<Instruction>(Op) || 3170b57cec5SDimitry Andric !fastSelectInstruction(cast<Instruction>(Op))) 3180b57cec5SDimitry Andric return 0; 3190b57cec5SDimitry Andric Reg = lookUpRegForValue(Op); 3200b57cec5SDimitry Andric } else if (isa<UndefValue>(V)) { 3210b57cec5SDimitry Andric Reg = createResultReg(TLI.getRegClassFor(VT)); 322bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, 3230b57cec5SDimitry Andric TII.get(TargetOpcode::IMPLICIT_DEF), Reg); 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric return Reg; 3260b57cec5SDimitry Andric } 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric /// Helper for getRegForValue. This function is called when the value isn't 3290b57cec5SDimitry Andric /// already available in a register and must be materialized with new 3300b57cec5SDimitry Andric /// instructions. 3315ffd83dbSDimitry Andric Register FastISel::materializeRegForValue(const Value *V, MVT VT) { 3325ffd83dbSDimitry Andric Register Reg; 3330b57cec5SDimitry Andric // Give the target-specific code a try first. 3340b57cec5SDimitry Andric if (isa<Constant>(V)) 3350b57cec5SDimitry Andric Reg = fastMaterializeConstant(cast<Constant>(V)); 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric // If target-specific code couldn't or didn't want to handle the value, then 3380b57cec5SDimitry Andric // give target-independent code a try. 3390b57cec5SDimitry Andric if (!Reg) 3400b57cec5SDimitry Andric Reg = materializeConstant(V, VT); 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric // Don't cache constant materializations in the general ValueMap. 3430b57cec5SDimitry Andric // To do so would require tracking what uses they dominate. 3440b57cec5SDimitry Andric if (Reg) { 3450b57cec5SDimitry Andric LocalValueMap[V] = Reg; 3460b57cec5SDimitry Andric LastLocalValue = MRI.getVRegDef(Reg); 3470b57cec5SDimitry Andric } 3480b57cec5SDimitry Andric return Reg; 3490b57cec5SDimitry Andric } 3500b57cec5SDimitry Andric 3515ffd83dbSDimitry Andric Register FastISel::lookUpRegForValue(const Value *V) { 3520b57cec5SDimitry Andric // Look up the value to see if we already have a register for it. We 3530b57cec5SDimitry Andric // cache values defined by Instructions across blocks, and other values 3540b57cec5SDimitry Andric // only locally. This is because Instructions already have the SSA 3550b57cec5SDimitry Andric // def-dominates-use requirement enforced. 3565ffd83dbSDimitry Andric DenseMap<const Value *, Register>::iterator I = FuncInfo.ValueMap.find(V); 3570b57cec5SDimitry Andric if (I != FuncInfo.ValueMap.end()) 3580b57cec5SDimitry Andric return I->second; 3590b57cec5SDimitry Andric return LocalValueMap[V]; 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric 3625ffd83dbSDimitry Andric void FastISel::updateValueMap(const Value *I, Register Reg, unsigned NumRegs) { 3630b57cec5SDimitry Andric if (!isa<Instruction>(I)) { 3640b57cec5SDimitry Andric LocalValueMap[I] = Reg; 3650b57cec5SDimitry Andric return; 3660b57cec5SDimitry Andric } 3670b57cec5SDimitry Andric 3685ffd83dbSDimitry Andric Register &AssignedReg = FuncInfo.ValueMap[I]; 3695ffd83dbSDimitry Andric if (!AssignedReg) 3700b57cec5SDimitry Andric // Use the new register. 3710b57cec5SDimitry Andric AssignedReg = Reg; 3720b57cec5SDimitry Andric else if (Reg != AssignedReg) { 3730b57cec5SDimitry Andric // Arrange for uses of AssignedReg to be replaced by uses of Reg. 3740b57cec5SDimitry Andric for (unsigned i = 0; i < NumRegs; i++) { 3750b57cec5SDimitry Andric FuncInfo.RegFixups[AssignedReg + i] = Reg + i; 3760b57cec5SDimitry Andric FuncInfo.RegsWithFixups.insert(Reg + i); 3770b57cec5SDimitry Andric } 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric AssignedReg = Reg; 3800b57cec5SDimitry Andric } 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 383*5deeebd8SDimitry Andric Register FastISel::getRegForGEPIndex(MVT PtrVT, const Value *Idx) { 3845ffd83dbSDimitry Andric Register IdxN = getRegForValue(Idx); 3855ffd83dbSDimitry Andric if (!IdxN) 3860b57cec5SDimitry Andric // Unhandled operand. Halt "fast" selection and bail. 387fe6060f1SDimitry Andric return Register(); 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric // If the index is smaller or larger than intptr_t, truncate or extend it. 3900b57cec5SDimitry Andric EVT IdxVT = EVT::getEVT(Idx->getType(), /*HandleUnknown=*/false); 3910b57cec5SDimitry Andric if (IdxVT.bitsLT(PtrVT)) { 392fe6060f1SDimitry Andric IdxN = fastEmit_r(IdxVT.getSimpleVT(), PtrVT, ISD::SIGN_EXTEND, IdxN); 3930b57cec5SDimitry Andric } else if (IdxVT.bitsGT(PtrVT)) { 3940b57cec5SDimitry Andric IdxN = 395fe6060f1SDimitry Andric fastEmit_r(IdxVT.getSimpleVT(), PtrVT, ISD::TRUNCATE, IdxN); 3960b57cec5SDimitry Andric } 397fe6060f1SDimitry Andric return IdxN; 3980b57cec5SDimitry Andric } 3990b57cec5SDimitry Andric 400*5deeebd8SDimitry Andric Register FastISel::getRegForGEPIndex(const Value *Idx) { 401*5deeebd8SDimitry Andric return getRegForGEPIndex(TLI.getPointerTy(DL), Idx); 402*5deeebd8SDimitry Andric } 403*5deeebd8SDimitry Andric 4040b57cec5SDimitry Andric void FastISel::recomputeInsertPt() { 4050b57cec5SDimitry Andric if (getLastLocalValue()) { 4060b57cec5SDimitry Andric FuncInfo.InsertPt = getLastLocalValue(); 4070b57cec5SDimitry Andric FuncInfo.MBB = FuncInfo.InsertPt->getParent(); 4080b57cec5SDimitry Andric ++FuncInfo.InsertPt; 4090b57cec5SDimitry Andric } else 4100b57cec5SDimitry Andric FuncInfo.InsertPt = FuncInfo.MBB->getFirstNonPHI(); 4110b57cec5SDimitry Andric } 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric void FastISel::removeDeadCode(MachineBasicBlock::iterator I, 4140b57cec5SDimitry Andric MachineBasicBlock::iterator E) { 4150b57cec5SDimitry Andric assert(I.isValid() && E.isValid() && std::distance(I, E) > 0 && 4160b57cec5SDimitry Andric "Invalid iterator!"); 4170b57cec5SDimitry Andric while (I != E) { 4180b57cec5SDimitry Andric if (SavedInsertPt == I) 4190b57cec5SDimitry Andric SavedInsertPt = E; 4200b57cec5SDimitry Andric if (EmitStartPt == I) 4210b57cec5SDimitry Andric EmitStartPt = E.isValid() ? &*E : nullptr; 4220b57cec5SDimitry Andric if (LastLocalValue == I) 4230b57cec5SDimitry Andric LastLocalValue = E.isValid() ? &*E : nullptr; 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric MachineInstr *Dead = &*I; 4260b57cec5SDimitry Andric ++I; 4270b57cec5SDimitry Andric Dead->eraseFromParent(); 4280b57cec5SDimitry Andric ++NumFastIselDead; 4290b57cec5SDimitry Andric } 4300b57cec5SDimitry Andric recomputeInsertPt(); 4310b57cec5SDimitry Andric } 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric FastISel::SavePoint FastISel::enterLocalValueArea() { 434e8d8bef9SDimitry Andric SavePoint OldInsertPt = FuncInfo.InsertPt; 4350b57cec5SDimitry Andric recomputeInsertPt(); 436e8d8bef9SDimitry Andric return OldInsertPt; 4370b57cec5SDimitry Andric } 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric void FastISel::leaveLocalValueArea(SavePoint OldInsertPt) { 4400b57cec5SDimitry Andric if (FuncInfo.InsertPt != FuncInfo.MBB->begin()) 4410b57cec5SDimitry Andric LastLocalValue = &*std::prev(FuncInfo.InsertPt); 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric // Restore the previous insert position. 444e8d8bef9SDimitry Andric FuncInfo.InsertPt = OldInsertPt; 4450b57cec5SDimitry Andric } 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andric bool FastISel::selectBinaryOp(const User *I, unsigned ISDOpcode) { 4480b57cec5SDimitry Andric EVT VT = EVT::getEVT(I->getType(), /*HandleUnknown=*/true); 4490b57cec5SDimitry Andric if (VT == MVT::Other || !VT.isSimple()) 4500b57cec5SDimitry Andric // Unhandled type. Halt "fast" selection and bail. 4510b57cec5SDimitry Andric return false; 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric // We only handle legal types. For example, on x86-32 the instruction 4540b57cec5SDimitry Andric // selector contains all of the 64-bit instructions from x86-64, 4550b57cec5SDimitry Andric // under the assumption that i64 won't be used if the target doesn't 4560b57cec5SDimitry Andric // support it. 4570b57cec5SDimitry Andric if (!TLI.isTypeLegal(VT)) { 4580b57cec5SDimitry Andric // MVT::i1 is special. Allow AND, OR, or XOR because they 4590b57cec5SDimitry Andric // don't require additional zeroing, which makes them easy. 46006c3fb27SDimitry Andric if (VT == MVT::i1 && ISD::isBitwiseLogicOp(ISDOpcode)) 4610b57cec5SDimitry Andric VT = TLI.getTypeToTransformTo(I->getContext(), VT); 4620b57cec5SDimitry Andric else 4630b57cec5SDimitry Andric return false; 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric // Check if the first operand is a constant, and handle it as "ri". At -O0, 4670b57cec5SDimitry Andric // we don't have anything that canonicalizes operand order. 4680b57cec5SDimitry Andric if (const auto *CI = dyn_cast<ConstantInt>(I->getOperand(0))) 4690b57cec5SDimitry Andric if (isa<Instruction>(I) && cast<Instruction>(I)->isCommutative()) { 4705ffd83dbSDimitry Andric Register Op1 = getRegForValue(I->getOperand(1)); 4710b57cec5SDimitry Andric if (!Op1) 4720b57cec5SDimitry Andric return false; 4730b57cec5SDimitry Andric 4745ffd83dbSDimitry Andric Register ResultReg = 475fe6060f1SDimitry Andric fastEmit_ri_(VT.getSimpleVT(), ISDOpcode, Op1, CI->getZExtValue(), 476fe6060f1SDimitry Andric VT.getSimpleVT()); 4770b57cec5SDimitry Andric if (!ResultReg) 4780b57cec5SDimitry Andric return false; 4790b57cec5SDimitry Andric 4800b57cec5SDimitry Andric // We successfully emitted code for the given LLVM Instruction. 4810b57cec5SDimitry Andric updateValueMap(I, ResultReg); 4820b57cec5SDimitry Andric return true; 4830b57cec5SDimitry Andric } 4840b57cec5SDimitry Andric 4855ffd83dbSDimitry Andric Register Op0 = getRegForValue(I->getOperand(0)); 4860b57cec5SDimitry Andric if (!Op0) // Unhandled operand. Halt "fast" selection and bail. 4870b57cec5SDimitry Andric return false; 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric // Check if the second operand is a constant and handle it appropriately. 4900b57cec5SDimitry Andric if (const auto *CI = dyn_cast<ConstantInt>(I->getOperand(1))) { 4910b57cec5SDimitry Andric uint64_t Imm = CI->getSExtValue(); 4920b57cec5SDimitry Andric 4930b57cec5SDimitry Andric // Transform "sdiv exact X, 8" -> "sra X, 3". 4940b57cec5SDimitry Andric if (ISDOpcode == ISD::SDIV && isa<BinaryOperator>(I) && 4950b57cec5SDimitry Andric cast<BinaryOperator>(I)->isExact() && isPowerOf2_64(Imm)) { 4960b57cec5SDimitry Andric Imm = Log2_64(Imm); 4970b57cec5SDimitry Andric ISDOpcode = ISD::SRA; 4980b57cec5SDimitry Andric } 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric // Transform "urem x, pow2" -> "and x, pow2-1". 5010b57cec5SDimitry Andric if (ISDOpcode == ISD::UREM && isa<BinaryOperator>(I) && 5020b57cec5SDimitry Andric isPowerOf2_64(Imm)) { 5030b57cec5SDimitry Andric --Imm; 5040b57cec5SDimitry Andric ISDOpcode = ISD::AND; 5050b57cec5SDimitry Andric } 5060b57cec5SDimitry Andric 507fe6060f1SDimitry Andric Register ResultReg = fastEmit_ri_(VT.getSimpleVT(), ISDOpcode, Op0, Imm, 508fe6060f1SDimitry Andric VT.getSimpleVT()); 5090b57cec5SDimitry Andric if (!ResultReg) 5100b57cec5SDimitry Andric return false; 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric // We successfully emitted code for the given LLVM Instruction. 5130b57cec5SDimitry Andric updateValueMap(I, ResultReg); 5140b57cec5SDimitry Andric return true; 5150b57cec5SDimitry Andric } 5160b57cec5SDimitry Andric 5175ffd83dbSDimitry Andric Register Op1 = getRegForValue(I->getOperand(1)); 5180b57cec5SDimitry Andric if (!Op1) // Unhandled operand. Halt "fast" selection and bail. 5190b57cec5SDimitry Andric return false; 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric // Now we have both operands in registers. Emit the instruction. 5225ffd83dbSDimitry Andric Register ResultReg = fastEmit_rr(VT.getSimpleVT(), VT.getSimpleVT(), 523fe6060f1SDimitry Andric ISDOpcode, Op0, Op1); 5240b57cec5SDimitry Andric if (!ResultReg) 5250b57cec5SDimitry Andric // Target-specific code wasn't able to find a machine opcode for 5260b57cec5SDimitry Andric // the given ISD opcode and type. Halt "fast" selection and bail. 5270b57cec5SDimitry Andric return false; 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric // We successfully emitted code for the given LLVM Instruction. 5300b57cec5SDimitry Andric updateValueMap(I, ResultReg); 5310b57cec5SDimitry Andric return true; 5320b57cec5SDimitry Andric } 5330b57cec5SDimitry Andric 5340b57cec5SDimitry Andric bool FastISel::selectGetElementPtr(const User *I) { 5355ffd83dbSDimitry Andric Register N = getRegForValue(I->getOperand(0)); 5360b57cec5SDimitry Andric if (!N) // Unhandled operand. Halt "fast" selection and bail. 5370b57cec5SDimitry Andric return false; 53816d6b3b3SDimitry Andric 53916d6b3b3SDimitry Andric // FIXME: The code below does not handle vector GEPs. Halt "fast" selection 54016d6b3b3SDimitry Andric // and bail. 54116d6b3b3SDimitry Andric if (isa<VectorType>(I->getType())) 54216d6b3b3SDimitry Andric return false; 54316d6b3b3SDimitry Andric 5440b57cec5SDimitry Andric // Keep a running tab of the total offset to coalesce multiple N = N + Offset 5450b57cec5SDimitry Andric // into a single N = N + TotalOffset. 5460b57cec5SDimitry Andric uint64_t TotalOffs = 0; 5470b57cec5SDimitry Andric // FIXME: What's a good SWAG number for MaxOffs? 5480b57cec5SDimitry Andric uint64_t MaxOffs = 2048; 549*5deeebd8SDimitry Andric MVT VT = TLI.getValueType(DL, I->getType()).getSimpleVT(); 550*5deeebd8SDimitry Andric 5510b57cec5SDimitry Andric for (gep_type_iterator GTI = gep_type_begin(I), E = gep_type_end(I); 5520b57cec5SDimitry Andric GTI != E; ++GTI) { 5530b57cec5SDimitry Andric const Value *Idx = GTI.getOperand(); 5540b57cec5SDimitry Andric if (StructType *StTy = GTI.getStructTypeOrNull()) { 5550b57cec5SDimitry Andric uint64_t Field = cast<ConstantInt>(Idx)->getZExtValue(); 5560b57cec5SDimitry Andric if (Field) { 5570b57cec5SDimitry Andric // N = N + Offset 5580b57cec5SDimitry Andric TotalOffs += DL.getStructLayout(StTy)->getElementOffset(Field); 5590b57cec5SDimitry Andric if (TotalOffs >= MaxOffs) { 560fe6060f1SDimitry Andric N = fastEmit_ri_(VT, ISD::ADD, N, TotalOffs, VT); 5610b57cec5SDimitry Andric if (!N) // Unhandled operand. Halt "fast" selection and bail. 5620b57cec5SDimitry Andric return false; 5630b57cec5SDimitry Andric TotalOffs = 0; 5640b57cec5SDimitry Andric } 5650b57cec5SDimitry Andric } 5660b57cec5SDimitry Andric } else { 5670b57cec5SDimitry Andric // If this is a constant subscript, handle it quickly. 5680b57cec5SDimitry Andric if (const auto *CI = dyn_cast<ConstantInt>(Idx)) { 5690b57cec5SDimitry Andric if (CI->isZero()) 5700b57cec5SDimitry Andric continue; 5710b57cec5SDimitry Andric // N = N + Offset 5720b57cec5SDimitry Andric uint64_t IdxN = CI->getValue().sextOrTrunc(64).getSExtValue(); 5731db9f3b2SDimitry Andric TotalOffs += GTI.getSequentialElementStride(DL) * IdxN; 5740b57cec5SDimitry Andric if (TotalOffs >= MaxOffs) { 575fe6060f1SDimitry Andric N = fastEmit_ri_(VT, ISD::ADD, N, TotalOffs, VT); 5760b57cec5SDimitry Andric if (!N) // Unhandled operand. Halt "fast" selection and bail. 5770b57cec5SDimitry Andric return false; 5780b57cec5SDimitry Andric TotalOffs = 0; 5790b57cec5SDimitry Andric } 5800b57cec5SDimitry Andric continue; 5810b57cec5SDimitry Andric } 5820b57cec5SDimitry Andric if (TotalOffs) { 583fe6060f1SDimitry Andric N = fastEmit_ri_(VT, ISD::ADD, N, TotalOffs, VT); 5840b57cec5SDimitry Andric if (!N) // Unhandled operand. Halt "fast" selection and bail. 5850b57cec5SDimitry Andric return false; 5860b57cec5SDimitry Andric TotalOffs = 0; 5870b57cec5SDimitry Andric } 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric // N = N + Idx * ElementSize; 5901db9f3b2SDimitry Andric uint64_t ElementSize = GTI.getSequentialElementStride(DL); 591*5deeebd8SDimitry Andric Register IdxN = getRegForGEPIndex(VT, Idx); 5920b57cec5SDimitry Andric if (!IdxN) // Unhandled operand. Halt "fast" selection and bail. 5930b57cec5SDimitry Andric return false; 5940b57cec5SDimitry Andric 5950b57cec5SDimitry Andric if (ElementSize != 1) { 596fe6060f1SDimitry Andric IdxN = fastEmit_ri_(VT, ISD::MUL, IdxN, ElementSize, VT); 5970b57cec5SDimitry Andric if (!IdxN) // Unhandled operand. Halt "fast" selection and bail. 5980b57cec5SDimitry Andric return false; 5990b57cec5SDimitry Andric } 600fe6060f1SDimitry Andric N = fastEmit_rr(VT, VT, ISD::ADD, N, IdxN); 6010b57cec5SDimitry Andric if (!N) // Unhandled operand. Halt "fast" selection and bail. 6020b57cec5SDimitry Andric return false; 6030b57cec5SDimitry Andric } 6040b57cec5SDimitry Andric } 6050b57cec5SDimitry Andric if (TotalOffs) { 606fe6060f1SDimitry Andric N = fastEmit_ri_(VT, ISD::ADD, N, TotalOffs, VT); 6070b57cec5SDimitry Andric if (!N) // Unhandled operand. Halt "fast" selection and bail. 6080b57cec5SDimitry Andric return false; 6090b57cec5SDimitry Andric } 6100b57cec5SDimitry Andric 6110b57cec5SDimitry Andric // We successfully emitted code for the given LLVM Instruction. 6120b57cec5SDimitry Andric updateValueMap(I, N); 6130b57cec5SDimitry Andric return true; 6140b57cec5SDimitry Andric } 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric bool FastISel::addStackMapLiveVars(SmallVectorImpl<MachineOperand> &Ops, 6170b57cec5SDimitry Andric const CallInst *CI, unsigned StartIdx) { 618349cc55cSDimitry Andric for (unsigned i = StartIdx, e = CI->arg_size(); i != e; ++i) { 6190b57cec5SDimitry Andric Value *Val = CI->getArgOperand(i); 6200b57cec5SDimitry Andric // Check for constants and encode them with a StackMaps::ConstantOp prefix. 6210b57cec5SDimitry Andric if (const auto *C = dyn_cast<ConstantInt>(Val)) { 6220b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateImm(StackMaps::ConstantOp)); 6230b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateImm(C->getSExtValue())); 6240b57cec5SDimitry Andric } else if (isa<ConstantPointerNull>(Val)) { 6250b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateImm(StackMaps::ConstantOp)); 6260b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateImm(0)); 6270b57cec5SDimitry Andric } else if (auto *AI = dyn_cast<AllocaInst>(Val)) { 6280b57cec5SDimitry Andric // Values coming from a stack location also require a special encoding, 6290b57cec5SDimitry Andric // but that is added later on by the target specific frame index 6300b57cec5SDimitry Andric // elimination implementation. 6310b57cec5SDimitry Andric auto SI = FuncInfo.StaticAllocaMap.find(AI); 6320b57cec5SDimitry Andric if (SI != FuncInfo.StaticAllocaMap.end()) 6330b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateFI(SI->second)); 6340b57cec5SDimitry Andric else 6350b57cec5SDimitry Andric return false; 6360b57cec5SDimitry Andric } else { 6375ffd83dbSDimitry Andric Register Reg = getRegForValue(Val); 6380b57cec5SDimitry Andric if (!Reg) 6390b57cec5SDimitry Andric return false; 6400b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateReg(Reg, /*isDef=*/false)); 6410b57cec5SDimitry Andric } 6420b57cec5SDimitry Andric } 6430b57cec5SDimitry Andric return true; 6440b57cec5SDimitry Andric } 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric bool FastISel::selectStackmap(const CallInst *I) { 6470b57cec5SDimitry Andric // void @llvm.experimental.stackmap(i64 <id>, i32 <numShadowBytes>, 6480b57cec5SDimitry Andric // [live variables...]) 6490b57cec5SDimitry Andric assert(I->getCalledFunction()->getReturnType()->isVoidTy() && 6500b57cec5SDimitry Andric "Stackmap cannot return a value."); 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric // The stackmap intrinsic only records the live variables (the arguments 6530b57cec5SDimitry Andric // passed to it) and emits NOPS (if requested). Unlike the patchpoint 6540b57cec5SDimitry Andric // intrinsic, this won't be lowered to a function call. This means we don't 6550b57cec5SDimitry Andric // have to worry about calling conventions and target-specific lowering code. 6560b57cec5SDimitry Andric // Instead we perform the call lowering right here. 6570b57cec5SDimitry Andric // 6580b57cec5SDimitry Andric // CALLSEQ_START(0, 0...) 6590b57cec5SDimitry Andric // STACKMAP(id, nbytes, ...) 6600b57cec5SDimitry Andric // CALLSEQ_END(0, 0) 6610b57cec5SDimitry Andric // 6620b57cec5SDimitry Andric SmallVector<MachineOperand, 32> Ops; 6630b57cec5SDimitry Andric 6640b57cec5SDimitry Andric // Add the <id> and <numBytes> constants. 6650b57cec5SDimitry Andric assert(isa<ConstantInt>(I->getOperand(PatchPointOpers::IDPos)) && 6660b57cec5SDimitry Andric "Expected a constant integer."); 6670b57cec5SDimitry Andric const auto *ID = cast<ConstantInt>(I->getOperand(PatchPointOpers::IDPos)); 6680b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateImm(ID->getZExtValue())); 6690b57cec5SDimitry Andric 6700b57cec5SDimitry Andric assert(isa<ConstantInt>(I->getOperand(PatchPointOpers::NBytesPos)) && 6710b57cec5SDimitry Andric "Expected a constant integer."); 6720b57cec5SDimitry Andric const auto *NumBytes = 6730b57cec5SDimitry Andric cast<ConstantInt>(I->getOperand(PatchPointOpers::NBytesPos)); 6740b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateImm(NumBytes->getZExtValue())); 6750b57cec5SDimitry Andric 6760b57cec5SDimitry Andric // Push live variables for the stack map (skipping the first two arguments 6770b57cec5SDimitry Andric // <id> and <numBytes>). 6780b57cec5SDimitry Andric if (!addStackMapLiveVars(Ops, I, 2)) 6790b57cec5SDimitry Andric return false; 6800b57cec5SDimitry Andric 6810b57cec5SDimitry Andric // We are not adding any register mask info here, because the stackmap doesn't 6820b57cec5SDimitry Andric // clobber anything. 6830b57cec5SDimitry Andric 6840b57cec5SDimitry Andric // Add scratch registers as implicit def and early clobber. 6850b57cec5SDimitry Andric CallingConv::ID CC = I->getCallingConv(); 6860b57cec5SDimitry Andric const MCPhysReg *ScratchRegs = TLI.getScratchRegisters(CC); 6870b57cec5SDimitry Andric for (unsigned i = 0; ScratchRegs[i]; ++i) 6880b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateReg( 6890b57cec5SDimitry Andric ScratchRegs[i], /*isDef=*/true, /*isImp=*/true, /*isKill=*/false, 6900b57cec5SDimitry Andric /*isDead=*/false, /*isUndef=*/false, /*isEarlyClobber=*/true)); 6910b57cec5SDimitry Andric 6920b57cec5SDimitry Andric // Issue CALLSEQ_START 6930b57cec5SDimitry Andric unsigned AdjStackDown = TII.getCallFrameSetupOpcode(); 6940b57cec5SDimitry Andric auto Builder = 695bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AdjStackDown)); 6960b57cec5SDimitry Andric const MCInstrDesc &MCID = Builder.getInstr()->getDesc(); 6970b57cec5SDimitry Andric for (unsigned I = 0, E = MCID.getNumOperands(); I < E; ++I) 6980b57cec5SDimitry Andric Builder.addImm(0); 6990b57cec5SDimitry Andric 7000b57cec5SDimitry Andric // Issue STACKMAP. 701bdd1243dSDimitry Andric MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, 7020b57cec5SDimitry Andric TII.get(TargetOpcode::STACKMAP)); 7030b57cec5SDimitry Andric for (auto const &MO : Ops) 7040b57cec5SDimitry Andric MIB.add(MO); 7050b57cec5SDimitry Andric 7060b57cec5SDimitry Andric // Issue CALLSEQ_END 7070b57cec5SDimitry Andric unsigned AdjStackUp = TII.getCallFrameDestroyOpcode(); 708bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(AdjStackUp)) 7090b57cec5SDimitry Andric .addImm(0) 7100b57cec5SDimitry Andric .addImm(0); 7110b57cec5SDimitry Andric 7120b57cec5SDimitry Andric // Inform the Frame Information that we have a stackmap in this function. 7130b57cec5SDimitry Andric FuncInfo.MF->getFrameInfo().setHasStackMap(); 7140b57cec5SDimitry Andric 7150b57cec5SDimitry Andric return true; 7160b57cec5SDimitry Andric } 7170b57cec5SDimitry Andric 7180b57cec5SDimitry Andric /// Lower an argument list according to the target calling convention. 7190b57cec5SDimitry Andric /// 7200b57cec5SDimitry Andric /// This is a helper for lowering intrinsics that follow a target calling 7210b57cec5SDimitry Andric /// convention or require stack pointer adjustment. Only a subset of the 7220b57cec5SDimitry Andric /// intrinsic's operands need to participate in the calling convention. 7230b57cec5SDimitry Andric bool FastISel::lowerCallOperands(const CallInst *CI, unsigned ArgIdx, 7240b57cec5SDimitry Andric unsigned NumArgs, const Value *Callee, 7250b57cec5SDimitry Andric bool ForceRetVoidTy, CallLoweringInfo &CLI) { 7260b57cec5SDimitry Andric ArgListTy Args; 7270b57cec5SDimitry Andric Args.reserve(NumArgs); 7280b57cec5SDimitry Andric 7290b57cec5SDimitry Andric // Populate the argument list. 7300b57cec5SDimitry Andric for (unsigned ArgI = ArgIdx, ArgE = ArgIdx + NumArgs; ArgI != ArgE; ++ArgI) { 7310b57cec5SDimitry Andric Value *V = CI->getOperand(ArgI); 7320b57cec5SDimitry Andric 7330b57cec5SDimitry Andric assert(!V->getType()->isEmptyTy() && "Empty type passed to intrinsic."); 7340b57cec5SDimitry Andric 7350b57cec5SDimitry Andric ArgListEntry Entry; 7360b57cec5SDimitry Andric Entry.Val = V; 7370b57cec5SDimitry Andric Entry.Ty = V->getType(); 7385ffd83dbSDimitry Andric Entry.setAttributes(CI, ArgI); 7390b57cec5SDimitry Andric Args.push_back(Entry); 7400b57cec5SDimitry Andric } 7410b57cec5SDimitry Andric 7420b57cec5SDimitry Andric Type *RetTy = ForceRetVoidTy ? Type::getVoidTy(CI->getType()->getContext()) 7430b57cec5SDimitry Andric : CI->getType(); 7440b57cec5SDimitry Andric CLI.setCallee(CI->getCallingConv(), RetTy, Callee, std::move(Args), NumArgs); 7450b57cec5SDimitry Andric 7460b57cec5SDimitry Andric return lowerCallTo(CLI); 7470b57cec5SDimitry Andric } 7480b57cec5SDimitry Andric 7490b57cec5SDimitry Andric FastISel::CallLoweringInfo &FastISel::CallLoweringInfo::setCallee( 7500b57cec5SDimitry Andric const DataLayout &DL, MCContext &Ctx, CallingConv::ID CC, Type *ResultTy, 7510b57cec5SDimitry Andric StringRef Target, ArgListTy &&ArgsList, unsigned FixedArgs) { 7520b57cec5SDimitry Andric SmallString<32> MangledName; 7530b57cec5SDimitry Andric Mangler::getNameWithPrefix(MangledName, Target, DL); 7540b57cec5SDimitry Andric MCSymbol *Sym = Ctx.getOrCreateSymbol(MangledName); 7550b57cec5SDimitry Andric return setCallee(CC, ResultTy, Sym, std::move(ArgsList), FixedArgs); 7560b57cec5SDimitry Andric } 7570b57cec5SDimitry Andric 7580b57cec5SDimitry Andric bool FastISel::selectPatchpoint(const CallInst *I) { 7590fca6ea1SDimitry Andric // <ty> @llvm.experimental.patchpoint.<ty>(i64 <id>, 7600b57cec5SDimitry Andric // i32 <numBytes>, 7610b57cec5SDimitry Andric // i8* <target>, 7620b57cec5SDimitry Andric // i32 <numArgs>, 7630b57cec5SDimitry Andric // [Args...], 7640b57cec5SDimitry Andric // [live variables...]) 7650b57cec5SDimitry Andric CallingConv::ID CC = I->getCallingConv(); 7660b57cec5SDimitry Andric bool IsAnyRegCC = CC == CallingConv::AnyReg; 7670b57cec5SDimitry Andric bool HasDef = !I->getType()->isVoidTy(); 7680b57cec5SDimitry Andric Value *Callee = I->getOperand(PatchPointOpers::TargetPos)->stripPointerCasts(); 7690b57cec5SDimitry Andric 7700fca6ea1SDimitry Andric // Check if we can lower the return type when using anyregcc. 7710fca6ea1SDimitry Andric MVT ValueType; 7720fca6ea1SDimitry Andric if (IsAnyRegCC && HasDef) { 7730fca6ea1SDimitry Andric ValueType = TLI.getSimpleValueType(DL, I->getType(), /*AllowUnknown=*/true); 7740fca6ea1SDimitry Andric if (ValueType == MVT::Other) 7750fca6ea1SDimitry Andric return false; 7760fca6ea1SDimitry Andric } 7770fca6ea1SDimitry Andric 7780b57cec5SDimitry Andric // Get the real number of arguments participating in the call <numArgs> 7790b57cec5SDimitry Andric assert(isa<ConstantInt>(I->getOperand(PatchPointOpers::NArgPos)) && 7800b57cec5SDimitry Andric "Expected a constant integer."); 7810b57cec5SDimitry Andric const auto *NumArgsVal = 7820b57cec5SDimitry Andric cast<ConstantInt>(I->getOperand(PatchPointOpers::NArgPos)); 7830b57cec5SDimitry Andric unsigned NumArgs = NumArgsVal->getZExtValue(); 7840b57cec5SDimitry Andric 7850b57cec5SDimitry Andric // Skip the four meta args: <id>, <numNopBytes>, <target>, <numArgs> 7860b57cec5SDimitry Andric // This includes all meta-operands up to but not including CC. 7870b57cec5SDimitry Andric unsigned NumMetaOpers = PatchPointOpers::CCPos; 788349cc55cSDimitry Andric assert(I->arg_size() >= NumMetaOpers + NumArgs && 7890b57cec5SDimitry Andric "Not enough arguments provided to the patchpoint intrinsic"); 7900b57cec5SDimitry Andric 7910b57cec5SDimitry Andric // For AnyRegCC the arguments are lowered later on manually. 7920b57cec5SDimitry Andric unsigned NumCallArgs = IsAnyRegCC ? 0 : NumArgs; 7930b57cec5SDimitry Andric CallLoweringInfo CLI; 7940b57cec5SDimitry Andric CLI.setIsPatchPoint(); 7950b57cec5SDimitry Andric if (!lowerCallOperands(I, NumMetaOpers, NumCallArgs, Callee, IsAnyRegCC, CLI)) 7960b57cec5SDimitry Andric return false; 7970b57cec5SDimitry Andric 7980b57cec5SDimitry Andric assert(CLI.Call && "No call instruction specified."); 7990b57cec5SDimitry Andric 8000b57cec5SDimitry Andric SmallVector<MachineOperand, 32> Ops; 8010b57cec5SDimitry Andric 8020b57cec5SDimitry Andric // Add an explicit result reg if we use the anyreg calling convention. 8030b57cec5SDimitry Andric if (IsAnyRegCC && HasDef) { 8040b57cec5SDimitry Andric assert(CLI.NumResultRegs == 0 && "Unexpected result register."); 8050fca6ea1SDimitry Andric assert(ValueType.isValid()); 8060fca6ea1SDimitry Andric CLI.ResultReg = createResultReg(TLI.getRegClassFor(ValueType)); 8070b57cec5SDimitry Andric CLI.NumResultRegs = 1; 8080b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateReg(CLI.ResultReg, /*isDef=*/true)); 8090b57cec5SDimitry Andric } 8100b57cec5SDimitry Andric 8110b57cec5SDimitry Andric // Add the <id> and <numBytes> constants. 8120b57cec5SDimitry Andric assert(isa<ConstantInt>(I->getOperand(PatchPointOpers::IDPos)) && 8130b57cec5SDimitry Andric "Expected a constant integer."); 8140b57cec5SDimitry Andric const auto *ID = cast<ConstantInt>(I->getOperand(PatchPointOpers::IDPos)); 8150b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateImm(ID->getZExtValue())); 8160b57cec5SDimitry Andric 8170b57cec5SDimitry Andric assert(isa<ConstantInt>(I->getOperand(PatchPointOpers::NBytesPos)) && 8180b57cec5SDimitry Andric "Expected a constant integer."); 8190b57cec5SDimitry Andric const auto *NumBytes = 8200b57cec5SDimitry Andric cast<ConstantInt>(I->getOperand(PatchPointOpers::NBytesPos)); 8210b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateImm(NumBytes->getZExtValue())); 8220b57cec5SDimitry Andric 8230b57cec5SDimitry Andric // Add the call target. 8240b57cec5SDimitry Andric if (const auto *C = dyn_cast<IntToPtrInst>(Callee)) { 8250b57cec5SDimitry Andric uint64_t CalleeConstAddr = 8260b57cec5SDimitry Andric cast<ConstantInt>(C->getOperand(0))->getZExtValue(); 8270b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateImm(CalleeConstAddr)); 8280b57cec5SDimitry Andric } else if (const auto *C = dyn_cast<ConstantExpr>(Callee)) { 8290b57cec5SDimitry Andric if (C->getOpcode() == Instruction::IntToPtr) { 8300b57cec5SDimitry Andric uint64_t CalleeConstAddr = 8310b57cec5SDimitry Andric cast<ConstantInt>(C->getOperand(0))->getZExtValue(); 8320b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateImm(CalleeConstAddr)); 8330b57cec5SDimitry Andric } else 8340b57cec5SDimitry Andric llvm_unreachable("Unsupported ConstantExpr."); 8350b57cec5SDimitry Andric } else if (const auto *GV = dyn_cast<GlobalValue>(Callee)) { 8360b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateGA(GV, 0)); 8370b57cec5SDimitry Andric } else if (isa<ConstantPointerNull>(Callee)) 8380b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateImm(0)); 8390b57cec5SDimitry Andric else 8400b57cec5SDimitry Andric llvm_unreachable("Unsupported callee address."); 8410b57cec5SDimitry Andric 8420b57cec5SDimitry Andric // Adjust <numArgs> to account for any arguments that have been passed on 8430b57cec5SDimitry Andric // the stack instead. 8440b57cec5SDimitry Andric unsigned NumCallRegArgs = IsAnyRegCC ? NumArgs : CLI.OutRegs.size(); 8450b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateImm(NumCallRegArgs)); 8460b57cec5SDimitry Andric 8470b57cec5SDimitry Andric // Add the calling convention 8480b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateImm((unsigned)CC)); 8490b57cec5SDimitry Andric 8500b57cec5SDimitry Andric // Add the arguments we omitted previously. The register allocator should 8510b57cec5SDimitry Andric // place these in any free register. 8520b57cec5SDimitry Andric if (IsAnyRegCC) { 8530b57cec5SDimitry Andric for (unsigned i = NumMetaOpers, e = NumMetaOpers + NumArgs; i != e; ++i) { 8545ffd83dbSDimitry Andric Register Reg = getRegForValue(I->getArgOperand(i)); 8550b57cec5SDimitry Andric if (!Reg) 8560b57cec5SDimitry Andric return false; 8570b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateReg(Reg, /*isDef=*/false)); 8580b57cec5SDimitry Andric } 8590b57cec5SDimitry Andric } 8600b57cec5SDimitry Andric 8610b57cec5SDimitry Andric // Push the arguments from the call instruction. 8620b57cec5SDimitry Andric for (auto Reg : CLI.OutRegs) 8630b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateReg(Reg, /*isDef=*/false)); 8640b57cec5SDimitry Andric 8650b57cec5SDimitry Andric // Push live variables for the stack map. 8660b57cec5SDimitry Andric if (!addStackMapLiveVars(Ops, I, NumMetaOpers + NumArgs)) 8670b57cec5SDimitry Andric return false; 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric // Push the register mask info. 8700b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateRegMask( 8710b57cec5SDimitry Andric TRI.getCallPreservedMask(*FuncInfo.MF, CC))); 8720b57cec5SDimitry Andric 8730b57cec5SDimitry Andric // Add scratch registers as implicit def and early clobber. 8740b57cec5SDimitry Andric const MCPhysReg *ScratchRegs = TLI.getScratchRegisters(CC); 8750b57cec5SDimitry Andric for (unsigned i = 0; ScratchRegs[i]; ++i) 8760b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateReg( 8770b57cec5SDimitry Andric ScratchRegs[i], /*isDef=*/true, /*isImp=*/true, /*isKill=*/false, 8780b57cec5SDimitry Andric /*isDead=*/false, /*isUndef=*/false, /*isEarlyClobber=*/true)); 8790b57cec5SDimitry Andric 8800b57cec5SDimitry Andric // Add implicit defs (return values). 8810b57cec5SDimitry Andric for (auto Reg : CLI.InRegs) 8820b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateReg(Reg, /*isDef=*/true, 8830b57cec5SDimitry Andric /*isImp=*/true)); 8840b57cec5SDimitry Andric 8850b57cec5SDimitry Andric // Insert the patchpoint instruction before the call generated by the target. 886bdd1243dSDimitry Andric MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, CLI.Call, MIMD, 8870b57cec5SDimitry Andric TII.get(TargetOpcode::PATCHPOINT)); 8880b57cec5SDimitry Andric 8890b57cec5SDimitry Andric for (auto &MO : Ops) 8900b57cec5SDimitry Andric MIB.add(MO); 8910b57cec5SDimitry Andric 8920b57cec5SDimitry Andric MIB->setPhysRegsDeadExcept(CLI.InRegs, TRI); 8930b57cec5SDimitry Andric 8940b57cec5SDimitry Andric // Delete the original call instruction. 8950b57cec5SDimitry Andric CLI.Call->eraseFromParent(); 8960b57cec5SDimitry Andric 8970b57cec5SDimitry Andric // Inform the Frame Information that we have a patchpoint in this function. 8980b57cec5SDimitry Andric FuncInfo.MF->getFrameInfo().setHasPatchPoint(); 8990b57cec5SDimitry Andric 9000b57cec5SDimitry Andric if (CLI.NumResultRegs) 9010b57cec5SDimitry Andric updateValueMap(I, CLI.ResultReg, CLI.NumResultRegs); 9020b57cec5SDimitry Andric return true; 9030b57cec5SDimitry Andric } 9040b57cec5SDimitry Andric 9050b57cec5SDimitry Andric bool FastISel::selectXRayCustomEvent(const CallInst *I) { 9060b57cec5SDimitry Andric const auto &Triple = TM.getTargetTriple(); 90706c3fb27SDimitry Andric if (Triple.isAArch64(64) && Triple.getArch() != Triple::x86_64) 9080b57cec5SDimitry Andric return true; // don't do anything to this instruction. 9090b57cec5SDimitry Andric SmallVector<MachineOperand, 8> Ops; 9100b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateReg(getRegForValue(I->getArgOperand(0)), 9110b57cec5SDimitry Andric /*isDef=*/false)); 9120b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateReg(getRegForValue(I->getArgOperand(1)), 9130b57cec5SDimitry Andric /*isDef=*/false)); 9140b57cec5SDimitry Andric MachineInstrBuilder MIB = 915bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, 9160b57cec5SDimitry Andric TII.get(TargetOpcode::PATCHABLE_EVENT_CALL)); 9170b57cec5SDimitry Andric for (auto &MO : Ops) 9180b57cec5SDimitry Andric MIB.add(MO); 9190b57cec5SDimitry Andric 9200b57cec5SDimitry Andric // Insert the Patchable Event Call instruction, that gets lowered properly. 9210b57cec5SDimitry Andric return true; 9220b57cec5SDimitry Andric } 9230b57cec5SDimitry Andric 9240b57cec5SDimitry Andric bool FastISel::selectXRayTypedEvent(const CallInst *I) { 9250b57cec5SDimitry Andric const auto &Triple = TM.getTargetTriple(); 92606c3fb27SDimitry Andric if (Triple.isAArch64(64) && Triple.getArch() != Triple::x86_64) 9270b57cec5SDimitry Andric return true; // don't do anything to this instruction. 9280b57cec5SDimitry Andric SmallVector<MachineOperand, 8> Ops; 9290b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateReg(getRegForValue(I->getArgOperand(0)), 9300b57cec5SDimitry Andric /*isDef=*/false)); 9310b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateReg(getRegForValue(I->getArgOperand(1)), 9320b57cec5SDimitry Andric /*isDef=*/false)); 9330b57cec5SDimitry Andric Ops.push_back(MachineOperand::CreateReg(getRegForValue(I->getArgOperand(2)), 9340b57cec5SDimitry Andric /*isDef=*/false)); 9350b57cec5SDimitry Andric MachineInstrBuilder MIB = 936bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, 9370b57cec5SDimitry Andric TII.get(TargetOpcode::PATCHABLE_TYPED_EVENT_CALL)); 9380b57cec5SDimitry Andric for (auto &MO : Ops) 9390b57cec5SDimitry Andric MIB.add(MO); 9400b57cec5SDimitry Andric 9410b57cec5SDimitry Andric // Insert the Patchable Typed Event Call instruction, that gets lowered properly. 9420b57cec5SDimitry Andric return true; 9430b57cec5SDimitry Andric } 9440b57cec5SDimitry Andric 9450b57cec5SDimitry Andric /// Returns an AttributeList representing the attributes applied to the return 9460b57cec5SDimitry Andric /// value of the given call. 9470b57cec5SDimitry Andric static AttributeList getReturnAttrs(FastISel::CallLoweringInfo &CLI) { 9480b57cec5SDimitry Andric SmallVector<Attribute::AttrKind, 2> Attrs; 9490b57cec5SDimitry Andric if (CLI.RetSExt) 9500b57cec5SDimitry Andric Attrs.push_back(Attribute::SExt); 9510b57cec5SDimitry Andric if (CLI.RetZExt) 9520b57cec5SDimitry Andric Attrs.push_back(Attribute::ZExt); 9530b57cec5SDimitry Andric if (CLI.IsInReg) 9540b57cec5SDimitry Andric Attrs.push_back(Attribute::InReg); 9550b57cec5SDimitry Andric 9560b57cec5SDimitry Andric return AttributeList::get(CLI.RetTy->getContext(), AttributeList::ReturnIndex, 9570b57cec5SDimitry Andric Attrs); 9580b57cec5SDimitry Andric } 9590b57cec5SDimitry Andric 9600b57cec5SDimitry Andric bool FastISel::lowerCallTo(const CallInst *CI, const char *SymName, 9610b57cec5SDimitry Andric unsigned NumArgs) { 9620b57cec5SDimitry Andric MCContext &Ctx = MF->getContext(); 9630b57cec5SDimitry Andric SmallString<32> MangledName; 9640b57cec5SDimitry Andric Mangler::getNameWithPrefix(MangledName, SymName, DL); 9650b57cec5SDimitry Andric MCSymbol *Sym = Ctx.getOrCreateSymbol(MangledName); 9660b57cec5SDimitry Andric return lowerCallTo(CI, Sym, NumArgs); 9670b57cec5SDimitry Andric } 9680b57cec5SDimitry Andric 9690b57cec5SDimitry Andric bool FastISel::lowerCallTo(const CallInst *CI, MCSymbol *Symbol, 9700b57cec5SDimitry Andric unsigned NumArgs) { 9715ffd83dbSDimitry Andric FunctionType *FTy = CI->getFunctionType(); 9725ffd83dbSDimitry Andric Type *RetTy = CI->getType(); 9730b57cec5SDimitry Andric 9740b57cec5SDimitry Andric ArgListTy Args; 9750b57cec5SDimitry Andric Args.reserve(NumArgs); 9760b57cec5SDimitry Andric 9770b57cec5SDimitry Andric // Populate the argument list. 9780b57cec5SDimitry Andric // Attributes for args start at offset 1, after the return attribute. 9790b57cec5SDimitry Andric for (unsigned ArgI = 0; ArgI != NumArgs; ++ArgI) { 9800b57cec5SDimitry Andric Value *V = CI->getOperand(ArgI); 9810b57cec5SDimitry Andric 9820b57cec5SDimitry Andric assert(!V->getType()->isEmptyTy() && "Empty type passed to intrinsic."); 9830b57cec5SDimitry Andric 9840b57cec5SDimitry Andric ArgListEntry Entry; 9850b57cec5SDimitry Andric Entry.Val = V; 9860b57cec5SDimitry Andric Entry.Ty = V->getType(); 9875ffd83dbSDimitry Andric Entry.setAttributes(CI, ArgI); 9880b57cec5SDimitry Andric Args.push_back(Entry); 9890b57cec5SDimitry Andric } 9905ffd83dbSDimitry Andric TLI.markLibCallAttributes(MF, CI->getCallingConv(), Args); 9910b57cec5SDimitry Andric 9920b57cec5SDimitry Andric CallLoweringInfo CLI; 9935ffd83dbSDimitry Andric CLI.setCallee(RetTy, FTy, Symbol, std::move(Args), *CI, NumArgs); 9940b57cec5SDimitry Andric 9950b57cec5SDimitry Andric return lowerCallTo(CLI); 9960b57cec5SDimitry Andric } 9970b57cec5SDimitry Andric 9980b57cec5SDimitry Andric bool FastISel::lowerCallTo(CallLoweringInfo &CLI) { 9990b57cec5SDimitry Andric // Handle the incoming return values from the call. 10000b57cec5SDimitry Andric CLI.clearIns(); 10010b57cec5SDimitry Andric SmallVector<EVT, 4> RetTys; 10020b57cec5SDimitry Andric ComputeValueVTs(TLI, DL, CLI.RetTy, RetTys); 10030b57cec5SDimitry Andric 10040b57cec5SDimitry Andric SmallVector<ISD::OutputArg, 4> Outs; 10050b57cec5SDimitry Andric GetReturnInfo(CLI.CallConv, CLI.RetTy, getReturnAttrs(CLI), Outs, TLI, DL); 10060b57cec5SDimitry Andric 10070b57cec5SDimitry Andric bool CanLowerReturn = TLI.CanLowerReturn( 10080b57cec5SDimitry Andric CLI.CallConv, *FuncInfo.MF, CLI.IsVarArg, Outs, CLI.RetTy->getContext()); 10090b57cec5SDimitry Andric 10100b57cec5SDimitry Andric // FIXME: sret demotion isn't supported yet - bail out. 10110b57cec5SDimitry Andric if (!CanLowerReturn) 10120b57cec5SDimitry Andric return false; 10130b57cec5SDimitry Andric 1014cb14a3feSDimitry Andric for (EVT VT : RetTys) { 10150b57cec5SDimitry Andric MVT RegisterVT = TLI.getRegisterType(CLI.RetTy->getContext(), VT); 10160b57cec5SDimitry Andric unsigned NumRegs = TLI.getNumRegisters(CLI.RetTy->getContext(), VT); 10170b57cec5SDimitry Andric for (unsigned i = 0; i != NumRegs; ++i) { 10180b57cec5SDimitry Andric ISD::InputArg MyFlags; 10190b57cec5SDimitry Andric MyFlags.VT = RegisterVT; 10200b57cec5SDimitry Andric MyFlags.ArgVT = VT; 10210b57cec5SDimitry Andric MyFlags.Used = CLI.IsReturnValueUsed; 10220b57cec5SDimitry Andric if (CLI.RetSExt) 10230b57cec5SDimitry Andric MyFlags.Flags.setSExt(); 10240b57cec5SDimitry Andric if (CLI.RetZExt) 10250b57cec5SDimitry Andric MyFlags.Flags.setZExt(); 10260b57cec5SDimitry Andric if (CLI.IsInReg) 10270b57cec5SDimitry Andric MyFlags.Flags.setInReg(); 10280b57cec5SDimitry Andric CLI.Ins.push_back(MyFlags); 10290b57cec5SDimitry Andric } 10300b57cec5SDimitry Andric } 10310b57cec5SDimitry Andric 10320b57cec5SDimitry Andric // Handle all of the outgoing arguments. 10330b57cec5SDimitry Andric CLI.clearOuts(); 10340b57cec5SDimitry Andric for (auto &Arg : CLI.getArgs()) { 10350b57cec5SDimitry Andric Type *FinalType = Arg.Ty; 10360b57cec5SDimitry Andric if (Arg.IsByVal) 1037fe6060f1SDimitry Andric FinalType = Arg.IndirectType; 10380b57cec5SDimitry Andric bool NeedsRegBlock = TLI.functionArgumentNeedsConsecutiveRegisters( 1039fe6060f1SDimitry Andric FinalType, CLI.CallConv, CLI.IsVarArg, DL); 10400b57cec5SDimitry Andric 10410b57cec5SDimitry Andric ISD::ArgFlagsTy Flags; 10420b57cec5SDimitry Andric if (Arg.IsZExt) 10430b57cec5SDimitry Andric Flags.setZExt(); 10440b57cec5SDimitry Andric if (Arg.IsSExt) 10450b57cec5SDimitry Andric Flags.setSExt(); 10460b57cec5SDimitry Andric if (Arg.IsInReg) 10470b57cec5SDimitry Andric Flags.setInReg(); 10480b57cec5SDimitry Andric if (Arg.IsSRet) 10490b57cec5SDimitry Andric Flags.setSRet(); 10500b57cec5SDimitry Andric if (Arg.IsSwiftSelf) 10510b57cec5SDimitry Andric Flags.setSwiftSelf(); 1052fe6060f1SDimitry Andric if (Arg.IsSwiftAsync) 1053fe6060f1SDimitry Andric Flags.setSwiftAsync(); 10540b57cec5SDimitry Andric if (Arg.IsSwiftError) 10550b57cec5SDimitry Andric Flags.setSwiftError(); 1056480093f4SDimitry Andric if (Arg.IsCFGuardTarget) 1057480093f4SDimitry Andric Flags.setCFGuardTarget(); 10580b57cec5SDimitry Andric if (Arg.IsByVal) 10590b57cec5SDimitry Andric Flags.setByVal(); 10600b57cec5SDimitry Andric if (Arg.IsInAlloca) { 10610b57cec5SDimitry Andric Flags.setInAlloca(); 10620b57cec5SDimitry Andric // Set the byval flag for CCAssignFn callbacks that don't know about 10630b57cec5SDimitry Andric // inalloca. This way we can know how many bytes we should've allocated 10640b57cec5SDimitry Andric // and how many bytes a callee cleanup function will pop. If we port 10650b57cec5SDimitry Andric // inalloca to more targets, we'll have to add custom inalloca handling in 10660b57cec5SDimitry Andric // the various CC lowering callbacks. 10670b57cec5SDimitry Andric Flags.setByVal(); 10680b57cec5SDimitry Andric } 10695ffd83dbSDimitry Andric if (Arg.IsPreallocated) { 10705ffd83dbSDimitry Andric Flags.setPreallocated(); 10715ffd83dbSDimitry Andric // Set the byval flag for CCAssignFn callbacks that don't know about 10725ffd83dbSDimitry Andric // preallocated. This way we can know how many bytes we should've 10735ffd83dbSDimitry Andric // allocated and how many bytes a callee cleanup function will pop. If we 10745ffd83dbSDimitry Andric // port preallocated to more targets, we'll have to add custom 10755ffd83dbSDimitry Andric // preallocated handling in the various CC lowering callbacks. 10765ffd83dbSDimitry Andric Flags.setByVal(); 10775ffd83dbSDimitry Andric } 1078fe6060f1SDimitry Andric MaybeAlign MemAlign = Arg.Alignment; 10795ffd83dbSDimitry Andric if (Arg.IsByVal || Arg.IsInAlloca || Arg.IsPreallocated) { 1080fe6060f1SDimitry Andric unsigned FrameSize = DL.getTypeAllocSize(Arg.IndirectType); 10810b57cec5SDimitry Andric 10820b57cec5SDimitry Andric // For ByVal, alignment should come from FE. BE will guess if this info 10830b57cec5SDimitry Andric // is not there, but there are cases it cannot get right. 1084fe6060f1SDimitry Andric if (!MemAlign) 1085fe6060f1SDimitry Andric MemAlign = Align(TLI.getByValTypeAlignment(Arg.IndirectType, DL)); 10860b57cec5SDimitry Andric Flags.setByValSize(FrameSize); 1087fe6060f1SDimitry Andric } else if (!MemAlign) { 1088fe6060f1SDimitry Andric MemAlign = DL.getABITypeAlign(Arg.Ty); 10890b57cec5SDimitry Andric } 1090fe6060f1SDimitry Andric Flags.setMemAlign(*MemAlign); 10910b57cec5SDimitry Andric if (Arg.IsNest) 10920b57cec5SDimitry Andric Flags.setNest(); 10930b57cec5SDimitry Andric if (NeedsRegBlock) 10940b57cec5SDimitry Andric Flags.setInConsecutiveRegs(); 10955ffd83dbSDimitry Andric Flags.setOrigAlign(DL.getABITypeAlign(Arg.Ty)); 10960b57cec5SDimitry Andric CLI.OutVals.push_back(Arg.Val); 10970b57cec5SDimitry Andric CLI.OutFlags.push_back(Flags); 10980b57cec5SDimitry Andric } 10990b57cec5SDimitry Andric 11000b57cec5SDimitry Andric if (!fastLowerCall(CLI)) 11010b57cec5SDimitry Andric return false; 11020b57cec5SDimitry Andric 11030b57cec5SDimitry Andric // Set all unused physreg defs as dead. 11040b57cec5SDimitry Andric assert(CLI.Call && "No call instruction specified."); 11050b57cec5SDimitry Andric CLI.Call->setPhysRegsDeadExcept(CLI.InRegs, TRI); 11060b57cec5SDimitry Andric 11075ffd83dbSDimitry Andric if (CLI.NumResultRegs && CLI.CB) 11085ffd83dbSDimitry Andric updateValueMap(CLI.CB, CLI.ResultReg, CLI.NumResultRegs); 11090b57cec5SDimitry Andric 11100b57cec5SDimitry Andric // Set labels for heapallocsite call. 11115ffd83dbSDimitry Andric if (CLI.CB) 11125ffd83dbSDimitry Andric if (MDNode *MD = CLI.CB->getMetadata("heapallocsite")) 1113480093f4SDimitry Andric CLI.Call->setHeapAllocMarker(*MF, MD); 11140b57cec5SDimitry Andric 11150b57cec5SDimitry Andric return true; 11160b57cec5SDimitry Andric } 11170b57cec5SDimitry Andric 11180b57cec5SDimitry Andric bool FastISel::lowerCall(const CallInst *CI) { 11195ffd83dbSDimitry Andric FunctionType *FuncTy = CI->getFunctionType(); 11205ffd83dbSDimitry Andric Type *RetTy = CI->getType(); 11210b57cec5SDimitry Andric 11220b57cec5SDimitry Andric ArgListTy Args; 11230b57cec5SDimitry Andric ArgListEntry Entry; 11245ffd83dbSDimitry Andric Args.reserve(CI->arg_size()); 11250b57cec5SDimitry Andric 11265ffd83dbSDimitry Andric for (auto i = CI->arg_begin(), e = CI->arg_end(); i != e; ++i) { 11270b57cec5SDimitry Andric Value *V = *i; 11280b57cec5SDimitry Andric 11290b57cec5SDimitry Andric // Skip empty types 11300b57cec5SDimitry Andric if (V->getType()->isEmptyTy()) 11310b57cec5SDimitry Andric continue; 11320b57cec5SDimitry Andric 11330b57cec5SDimitry Andric Entry.Val = V; 11340b57cec5SDimitry Andric Entry.Ty = V->getType(); 11350b57cec5SDimitry Andric 11360b57cec5SDimitry Andric // Skip the first return-type Attribute to get to params. 11375ffd83dbSDimitry Andric Entry.setAttributes(CI, i - CI->arg_begin()); 11380b57cec5SDimitry Andric Args.push_back(Entry); 11390b57cec5SDimitry Andric } 11400b57cec5SDimitry Andric 11410b57cec5SDimitry Andric // Check if target-independent constraints permit a tail call here. 11420b57cec5SDimitry Andric // Target-dependent constraints are checked within fastLowerCall. 11430b57cec5SDimitry Andric bool IsTailCall = CI->isTailCall(); 11445ffd83dbSDimitry Andric if (IsTailCall && !isInTailCallPosition(*CI, TM)) 11450b57cec5SDimitry Andric IsTailCall = false; 1146bdd1243dSDimitry Andric if (IsTailCall && !CI->isMustTailCall() && 1147bdd1243dSDimitry Andric MF->getFunction().getFnAttribute("disable-tail-calls").getValueAsBool()) 1148480093f4SDimitry Andric IsTailCall = false; 11490b57cec5SDimitry Andric 11500b57cec5SDimitry Andric CallLoweringInfo CLI; 11515ffd83dbSDimitry Andric CLI.setCallee(RetTy, FuncTy, CI->getCalledOperand(), std::move(Args), *CI) 11520b57cec5SDimitry Andric .setTailCall(IsTailCall); 11530b57cec5SDimitry Andric 1154349cc55cSDimitry Andric diagnoseDontCall(*CI); 1155349cc55cSDimitry Andric 11560b57cec5SDimitry Andric return lowerCallTo(CLI); 11570b57cec5SDimitry Andric } 11580b57cec5SDimitry Andric 11590b57cec5SDimitry Andric bool FastISel::selectCall(const User *I) { 11600b57cec5SDimitry Andric const CallInst *Call = cast<CallInst>(I); 11610b57cec5SDimitry Andric 11620b57cec5SDimitry Andric // Handle simple inline asms. 11635ffd83dbSDimitry Andric if (const InlineAsm *IA = dyn_cast<InlineAsm>(Call->getCalledOperand())) { 11640b57cec5SDimitry Andric // Don't attempt to handle constraints. 11650b57cec5SDimitry Andric if (!IA->getConstraintString().empty()) 11660b57cec5SDimitry Andric return false; 11670b57cec5SDimitry Andric 11680b57cec5SDimitry Andric unsigned ExtraInfo = 0; 11690b57cec5SDimitry Andric if (IA->hasSideEffects()) 11700b57cec5SDimitry Andric ExtraInfo |= InlineAsm::Extra_HasSideEffects; 11710b57cec5SDimitry Andric if (IA->isAlignStack()) 11720b57cec5SDimitry Andric ExtraInfo |= InlineAsm::Extra_IsAlignStack; 11735ffd83dbSDimitry Andric if (Call->isConvergent()) 11745ffd83dbSDimitry Andric ExtraInfo |= InlineAsm::Extra_IsConvergent; 11758bcb0991SDimitry Andric ExtraInfo |= IA->getDialect() * InlineAsm::Extra_AsmDialect; 11760b57cec5SDimitry Andric 1177bdd1243dSDimitry Andric MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, 11785ffd83dbSDimitry Andric TII.get(TargetOpcode::INLINEASM)); 11795ffd83dbSDimitry Andric MIB.addExternalSymbol(IA->getAsmString().c_str()); 11805ffd83dbSDimitry Andric MIB.addImm(ExtraInfo); 11815ffd83dbSDimitry Andric 11825ffd83dbSDimitry Andric const MDNode *SrcLoc = Call->getMetadata("srcloc"); 11835ffd83dbSDimitry Andric if (SrcLoc) 11845ffd83dbSDimitry Andric MIB.addMetadata(SrcLoc); 11855ffd83dbSDimitry Andric 11860b57cec5SDimitry Andric return true; 11870b57cec5SDimitry Andric } 11880b57cec5SDimitry Andric 11890b57cec5SDimitry Andric // Handle intrinsic function calls. 11900b57cec5SDimitry Andric if (const auto *II = dyn_cast<IntrinsicInst>(Call)) 11910b57cec5SDimitry Andric return selectIntrinsicCall(II); 11920b57cec5SDimitry Andric 11930b57cec5SDimitry Andric return lowerCall(Call); 11940b57cec5SDimitry Andric } 11950b57cec5SDimitry Andric 11961db9f3b2SDimitry Andric void FastISel::handleDbgInfo(const Instruction *II) { 11970fca6ea1SDimitry Andric if (!II->hasDbgRecords()) 11981db9f3b2SDimitry Andric return; 11991db9f3b2SDimitry Andric 12001db9f3b2SDimitry Andric // Clear any metadata. 12011db9f3b2SDimitry Andric MIMD = MIMetadata(); 12021db9f3b2SDimitry Andric 12031db9f3b2SDimitry Andric // Reverse order of debug records, because fast-isel walks through backwards. 12040fca6ea1SDimitry Andric for (DbgRecord &DR : llvm::reverse(II->getDbgRecordRange())) { 12051db9f3b2SDimitry Andric flushLocalValueMap(); 12061db9f3b2SDimitry Andric recomputeInsertPt(); 12071db9f3b2SDimitry Andric 12080fca6ea1SDimitry Andric if (DbgLabelRecord *DLR = dyn_cast<DbgLabelRecord>(&DR)) { 12090fca6ea1SDimitry Andric assert(DLR->getLabel() && "Missing label"); 12100fca6ea1SDimitry Andric if (!FuncInfo.MF->getMMI().hasDebugInfo()) { 12110fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DLR << "\n"); 12120fca6ea1SDimitry Andric continue; 12130fca6ea1SDimitry Andric } 12140fca6ea1SDimitry Andric 12150fca6ea1SDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DLR->getDebugLoc(), 12160fca6ea1SDimitry Andric TII.get(TargetOpcode::DBG_LABEL)) 12170fca6ea1SDimitry Andric .addMetadata(DLR->getLabel()); 12180fca6ea1SDimitry Andric continue; 12190fca6ea1SDimitry Andric } 12200fca6ea1SDimitry Andric 12210fca6ea1SDimitry Andric DbgVariableRecord &DVR = cast<DbgVariableRecord>(DR); 12220fca6ea1SDimitry Andric 12231db9f3b2SDimitry Andric Value *V = nullptr; 12240fca6ea1SDimitry Andric if (!DVR.hasArgList()) 12250fca6ea1SDimitry Andric V = DVR.getVariableLocationOp(0); 12261db9f3b2SDimitry Andric 12271db9f3b2SDimitry Andric bool Res = false; 12280fca6ea1SDimitry Andric if (DVR.getType() == DbgVariableRecord::LocationType::Value || 12290fca6ea1SDimitry Andric DVR.getType() == DbgVariableRecord::LocationType::Assign) { 12300fca6ea1SDimitry Andric Res = lowerDbgValue(V, DVR.getExpression(), DVR.getVariable(), 12310fca6ea1SDimitry Andric DVR.getDebugLoc()); 12321db9f3b2SDimitry Andric } else { 12330fca6ea1SDimitry Andric assert(DVR.getType() == DbgVariableRecord::LocationType::Declare); 12340fca6ea1SDimitry Andric if (FuncInfo.PreprocessedDVRDeclares.contains(&DVR)) 12351db9f3b2SDimitry Andric continue; 12360fca6ea1SDimitry Andric Res = lowerDbgDeclare(V, DVR.getExpression(), DVR.getVariable(), 12370fca6ea1SDimitry Andric DVR.getDebugLoc()); 12381db9f3b2SDimitry Andric } 12391db9f3b2SDimitry Andric 12401db9f3b2SDimitry Andric if (!Res) 12410fca6ea1SDimitry Andric LLVM_DEBUG(dbgs() << "Dropping debug-info for " << DVR << "\n";); 12421db9f3b2SDimitry Andric } 12431db9f3b2SDimitry Andric } 12441db9f3b2SDimitry Andric 12451db9f3b2SDimitry Andric bool FastISel::lowerDbgValue(const Value *V, DIExpression *Expr, 12461db9f3b2SDimitry Andric DILocalVariable *Var, const DebugLoc &DL) { 12471db9f3b2SDimitry Andric // This form of DBG_VALUE is target-independent. 12481db9f3b2SDimitry Andric const MCInstrDesc &II = TII.get(TargetOpcode::DBG_VALUE); 12491db9f3b2SDimitry Andric if (!V || isa<UndefValue>(V)) { 12501db9f3b2SDimitry Andric // DI is either undef or cannot produce a valid DBG_VALUE, so produce an 12511db9f3b2SDimitry Andric // undef DBG_VALUE to terminate any prior location. 12521db9f3b2SDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, false, 0U, Var, Expr); 12531db9f3b2SDimitry Andric return true; 12541db9f3b2SDimitry Andric } 12551db9f3b2SDimitry Andric if (const auto *CI = dyn_cast<ConstantInt>(V)) { 12561db9f3b2SDimitry Andric // See if there's an expression to constant-fold. 12571db9f3b2SDimitry Andric if (Expr) 12581db9f3b2SDimitry Andric std::tie(Expr, CI) = Expr->constantFold(CI); 12591db9f3b2SDimitry Andric if (CI->getBitWidth() > 64) 12601db9f3b2SDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 12611db9f3b2SDimitry Andric .addCImm(CI) 12621db9f3b2SDimitry Andric .addImm(0U) 12631db9f3b2SDimitry Andric .addMetadata(Var) 12641db9f3b2SDimitry Andric .addMetadata(Expr); 12651db9f3b2SDimitry Andric else 12661db9f3b2SDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 12671db9f3b2SDimitry Andric .addImm(CI->getZExtValue()) 12681db9f3b2SDimitry Andric .addImm(0U) 12691db9f3b2SDimitry Andric .addMetadata(Var) 12701db9f3b2SDimitry Andric .addMetadata(Expr); 12711db9f3b2SDimitry Andric return true; 12721db9f3b2SDimitry Andric } 12731db9f3b2SDimitry Andric if (const auto *CF = dyn_cast<ConstantFP>(V)) { 12741db9f3b2SDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 12751db9f3b2SDimitry Andric .addFPImm(CF) 12761db9f3b2SDimitry Andric .addImm(0U) 12771db9f3b2SDimitry Andric .addMetadata(Var) 12781db9f3b2SDimitry Andric .addMetadata(Expr); 12791db9f3b2SDimitry Andric return true; 12801db9f3b2SDimitry Andric } 12811db9f3b2SDimitry Andric if (const auto *Arg = dyn_cast<Argument>(V); 12821db9f3b2SDimitry Andric Arg && Expr && Expr->isEntryValue()) { 12831db9f3b2SDimitry Andric // As per the Verifier, this case is only valid for swift async Args. 12841db9f3b2SDimitry Andric assert(Arg->hasAttribute(Attribute::AttrKind::SwiftAsync)); 12851db9f3b2SDimitry Andric 12861db9f3b2SDimitry Andric Register Reg = getRegForValue(Arg); 12871db9f3b2SDimitry Andric for (auto [PhysReg, VirtReg] : FuncInfo.RegInfo->liveins()) 12881db9f3b2SDimitry Andric if (Reg == VirtReg || Reg == PhysReg) { 12891db9f3b2SDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, false /*IsIndirect*/, 12901db9f3b2SDimitry Andric PhysReg, Var, Expr); 12911db9f3b2SDimitry Andric return true; 12921db9f3b2SDimitry Andric } 12931db9f3b2SDimitry Andric 12941db9f3b2SDimitry Andric LLVM_DEBUG(dbgs() << "Dropping dbg.value: expression is entry_value but " 12951db9f3b2SDimitry Andric "couldn't find a physical register\n"); 12961db9f3b2SDimitry Andric return false; 12971db9f3b2SDimitry Andric } 12981db9f3b2SDimitry Andric if (auto SI = FuncInfo.StaticAllocaMap.find(dyn_cast<AllocaInst>(V)); 12991db9f3b2SDimitry Andric SI != FuncInfo.StaticAllocaMap.end()) { 13001db9f3b2SDimitry Andric MachineOperand FrameIndexOp = MachineOperand::CreateFI(SI->second); 13011db9f3b2SDimitry Andric bool IsIndirect = false; 13021db9f3b2SDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, IsIndirect, FrameIndexOp, 13031db9f3b2SDimitry Andric Var, Expr); 13041db9f3b2SDimitry Andric return true; 13051db9f3b2SDimitry Andric } 13061db9f3b2SDimitry Andric if (Register Reg = lookUpRegForValue(V)) { 13071db9f3b2SDimitry Andric // FIXME: This does not handle register-indirect values at offset 0. 13081db9f3b2SDimitry Andric if (!FuncInfo.MF->useDebugInstrRef()) { 13091db9f3b2SDimitry Andric bool IsIndirect = false; 13101db9f3b2SDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, IsIndirect, Reg, Var, 13111db9f3b2SDimitry Andric Expr); 13121db9f3b2SDimitry Andric return true; 13131db9f3b2SDimitry Andric } 13141db9f3b2SDimitry Andric // If using instruction referencing, produce this as a DBG_INSTR_REF, 13151db9f3b2SDimitry Andric // to be later patched up by finalizeDebugInstrRefs. 13161db9f3b2SDimitry Andric SmallVector<MachineOperand, 1> MOs({MachineOperand::CreateReg( 13171db9f3b2SDimitry Andric /* Reg */ Reg, /* isDef */ false, /* isImp */ false, 13181db9f3b2SDimitry Andric /* isKill */ false, /* isDead */ false, 13191db9f3b2SDimitry Andric /* isUndef */ false, /* isEarlyClobber */ false, 13201db9f3b2SDimitry Andric /* SubReg */ 0, /* isDebug */ true)}); 13211db9f3b2SDimitry Andric SmallVector<uint64_t, 2> Ops({dwarf::DW_OP_LLVM_arg, 0}); 13221db9f3b2SDimitry Andric auto *NewExpr = DIExpression::prependOpcodes(Expr, Ops); 13231db9f3b2SDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 13241db9f3b2SDimitry Andric TII.get(TargetOpcode::DBG_INSTR_REF), /*IsIndirect*/ false, MOs, 13251db9f3b2SDimitry Andric Var, NewExpr); 13261db9f3b2SDimitry Andric return true; 13271db9f3b2SDimitry Andric } 13281db9f3b2SDimitry Andric return false; 13291db9f3b2SDimitry Andric } 13301db9f3b2SDimitry Andric 13311db9f3b2SDimitry Andric bool FastISel::lowerDbgDeclare(const Value *Address, DIExpression *Expr, 13321db9f3b2SDimitry Andric DILocalVariable *Var, const DebugLoc &DL) { 13331db9f3b2SDimitry Andric if (!Address || isa<UndefValue>(Address)) { 13341db9f3b2SDimitry Andric LLVM_DEBUG(dbgs() << "Dropping debug info (bad/undef address)\n"); 13351db9f3b2SDimitry Andric return false; 13361db9f3b2SDimitry Andric } 13371db9f3b2SDimitry Andric 13381db9f3b2SDimitry Andric std::optional<MachineOperand> Op; 13391db9f3b2SDimitry Andric if (Register Reg = lookUpRegForValue(Address)) 13401db9f3b2SDimitry Andric Op = MachineOperand::CreateReg(Reg, false); 13411db9f3b2SDimitry Andric 13421db9f3b2SDimitry Andric // If we have a VLA that has a "use" in a metadata node that's then used 13431db9f3b2SDimitry Andric // here but it has no other uses, then we have a problem. E.g., 13441db9f3b2SDimitry Andric // 13451db9f3b2SDimitry Andric // int foo (const int *x) { 13461db9f3b2SDimitry Andric // char a[*x]; 13471db9f3b2SDimitry Andric // return 0; 13481db9f3b2SDimitry Andric // } 13491db9f3b2SDimitry Andric // 13501db9f3b2SDimitry Andric // If we assign 'a' a vreg and fast isel later on has to use the selection 13511db9f3b2SDimitry Andric // DAG isel, it will want to copy the value to the vreg. However, there are 13521db9f3b2SDimitry Andric // no uses, which goes counter to what selection DAG isel expects. 13531db9f3b2SDimitry Andric if (!Op && !Address->use_empty() && isa<Instruction>(Address) && 13541db9f3b2SDimitry Andric (!isa<AllocaInst>(Address) || 13551db9f3b2SDimitry Andric !FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(Address)))) 13561db9f3b2SDimitry Andric Op = MachineOperand::CreateReg(FuncInfo.InitializeRegForValue(Address), 13571db9f3b2SDimitry Andric false); 13581db9f3b2SDimitry Andric 13591db9f3b2SDimitry Andric if (Op) { 13601db9f3b2SDimitry Andric assert(Var->isValidLocationForIntrinsic(DL) && 13611db9f3b2SDimitry Andric "Expected inlined-at fields to agree"); 13621db9f3b2SDimitry Andric if (FuncInfo.MF->useDebugInstrRef() && Op->isReg()) { 13631db9f3b2SDimitry Andric // If using instruction referencing, produce this as a DBG_INSTR_REF, 13641db9f3b2SDimitry Andric // to be later patched up by finalizeDebugInstrRefs. Tack a deref onto 13651db9f3b2SDimitry Andric // the expression, we don't have an "indirect" flag in DBG_INSTR_REF. 13661db9f3b2SDimitry Andric SmallVector<uint64_t, 3> Ops( 13671db9f3b2SDimitry Andric {dwarf::DW_OP_LLVM_arg, 0, dwarf::DW_OP_deref}); 13681db9f3b2SDimitry Andric auto *NewExpr = DIExpression::prependOpcodes(Expr, Ops); 13691db9f3b2SDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 13701db9f3b2SDimitry Andric TII.get(TargetOpcode::DBG_INSTR_REF), /*IsIndirect*/ false, *Op, 13711db9f3b2SDimitry Andric Var, NewExpr); 13721db9f3b2SDimitry Andric return true; 13731db9f3b2SDimitry Andric } 13741db9f3b2SDimitry Andric 13751db9f3b2SDimitry Andric // A dbg.declare describes the address of a source variable, so lower it 13761db9f3b2SDimitry Andric // into an indirect DBG_VALUE. 13771db9f3b2SDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 13781db9f3b2SDimitry Andric TII.get(TargetOpcode::DBG_VALUE), /*IsIndirect*/ true, *Op, Var, 13791db9f3b2SDimitry Andric Expr); 13801db9f3b2SDimitry Andric return true; 13811db9f3b2SDimitry Andric } 13821db9f3b2SDimitry Andric 13831db9f3b2SDimitry Andric // We can't yet handle anything else here because it would require 13841db9f3b2SDimitry Andric // generating code, thus altering codegen because of debug info. 13851db9f3b2SDimitry Andric LLVM_DEBUG( 13861db9f3b2SDimitry Andric dbgs() << "Dropping debug info (no materialized reg for address)\n"); 13871db9f3b2SDimitry Andric return false; 13881db9f3b2SDimitry Andric } 13891db9f3b2SDimitry Andric 13900b57cec5SDimitry Andric bool FastISel::selectIntrinsicCall(const IntrinsicInst *II) { 13910b57cec5SDimitry Andric switch (II->getIntrinsicID()) { 13920b57cec5SDimitry Andric default: 13930b57cec5SDimitry Andric break; 13940b57cec5SDimitry Andric // At -O0 we don't care about the lifetime intrinsics. 13950b57cec5SDimitry Andric case Intrinsic::lifetime_start: 13960b57cec5SDimitry Andric case Intrinsic::lifetime_end: 13970b57cec5SDimitry Andric // The donothing intrinsic does, well, nothing. 13980b57cec5SDimitry Andric case Intrinsic::donothing: 13990b57cec5SDimitry Andric // Neither does the sideeffect intrinsic. 14000b57cec5SDimitry Andric case Intrinsic::sideeffect: 14010b57cec5SDimitry Andric // Neither does the assume intrinsic; it's also OK not to codegen its operand. 14020b57cec5SDimitry Andric case Intrinsic::assume: 1403e8d8bef9SDimitry Andric // Neither does the llvm.experimental.noalias.scope.decl intrinsic 1404e8d8bef9SDimitry Andric case Intrinsic::experimental_noalias_scope_decl: 14050b57cec5SDimitry Andric return true; 14060b57cec5SDimitry Andric case Intrinsic::dbg_declare: { 14070b57cec5SDimitry Andric const DbgDeclareInst *DI = cast<DbgDeclareInst>(II); 14080b57cec5SDimitry Andric assert(DI->getVariable() && "Missing variable"); 14090b57cec5SDimitry Andric if (!FuncInfo.MF->getMMI().hasDebugInfo()) { 14105ffd83dbSDimitry Andric LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI 14115ffd83dbSDimitry Andric << " (!hasDebugInfo)\n"); 14120b57cec5SDimitry Andric return true; 14130b57cec5SDimitry Andric } 14140b57cec5SDimitry Andric 141506c3fb27SDimitry Andric if (FuncInfo.PreprocessedDbgDeclares.contains(DI)) 141606c3fb27SDimitry Andric return true; 141706c3fb27SDimitry Andric 14180b57cec5SDimitry Andric const Value *Address = DI->getAddress(); 14191db9f3b2SDimitry Andric if (!lowerDbgDeclare(Address, DI->getExpression(), DI->getVariable(), 14201db9f3b2SDimitry Andric MIMD.getDL())) 14211db9f3b2SDimitry Andric LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI); 14220b57cec5SDimitry Andric 14230b57cec5SDimitry Andric return true; 14240b57cec5SDimitry Andric } 14250fca6ea1SDimitry Andric case Intrinsic::dbg_assign: 14260fca6ea1SDimitry Andric // A dbg.assign is a dbg.value with more information, typically produced 14270fca6ea1SDimitry Andric // during optimisation. If one reaches fastisel then something odd has 14280fca6ea1SDimitry Andric // happened (such as an optimised function being always-inlined into an 14290fca6ea1SDimitry Andric // optnone function). We will not be using the extra information in the 14300fca6ea1SDimitry Andric // dbg.assign in that case, just use its dbg.value fields. 14310fca6ea1SDimitry Andric [[fallthrough]]; 14320b57cec5SDimitry Andric case Intrinsic::dbg_value: { 14330b57cec5SDimitry Andric // This form of DBG_VALUE is target-independent. 14340b57cec5SDimitry Andric const DbgValueInst *DI = cast<DbgValueInst>(II); 14350b57cec5SDimitry Andric const Value *V = DI->getValue(); 143606c3fb27SDimitry Andric DIExpression *Expr = DI->getExpression(); 143706c3fb27SDimitry Andric DILocalVariable *Var = DI->getVariable(); 14381db9f3b2SDimitry Andric if (DI->hasArgList()) 14391db9f3b2SDimitry Andric // Signal that we don't have a location for this. 14401db9f3b2SDimitry Andric V = nullptr; 14411db9f3b2SDimitry Andric 144206c3fb27SDimitry Andric assert(Var->isValidLocationForIntrinsic(MIMD.getDL()) && 14430b57cec5SDimitry Andric "Expected inlined-at fields to agree"); 144406c3fb27SDimitry Andric 14451db9f3b2SDimitry Andric if (!lowerDbgValue(V, Expr, Var, MIMD.getDL())) 14460b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n"); 14471db9f3b2SDimitry Andric 14480b57cec5SDimitry Andric return true; 14490b57cec5SDimitry Andric } 14500b57cec5SDimitry Andric case Intrinsic::dbg_label: { 14510b57cec5SDimitry Andric const DbgLabelInst *DI = cast<DbgLabelInst>(II); 14520b57cec5SDimitry Andric assert(DI->getLabel() && "Missing label"); 14530b57cec5SDimitry Andric if (!FuncInfo.MF->getMMI().hasDebugInfo()) { 14540b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Dropping debug info for " << *DI << "\n"); 14550b57cec5SDimitry Andric return true; 14560b57cec5SDimitry Andric } 14570b57cec5SDimitry Andric 1458bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, 14590b57cec5SDimitry Andric TII.get(TargetOpcode::DBG_LABEL)).addMetadata(DI->getLabel()); 14600b57cec5SDimitry Andric return true; 14610b57cec5SDimitry Andric } 14628bcb0991SDimitry Andric case Intrinsic::objectsize: 14638bcb0991SDimitry Andric llvm_unreachable("llvm.objectsize.* should have been lowered already"); 14648bcb0991SDimitry Andric 14658bcb0991SDimitry Andric case Intrinsic::is_constant: 14668bcb0991SDimitry Andric llvm_unreachable("llvm.is.constant.* should have been lowered already"); 14678bcb0991SDimitry Andric 14680fca6ea1SDimitry Andric case Intrinsic::allow_runtime_check: 14690fca6ea1SDimitry Andric case Intrinsic::allow_ubsan_check: { 14700fca6ea1SDimitry Andric Register ResultReg = getRegForValue(ConstantInt::getTrue(II->getType())); 14710fca6ea1SDimitry Andric if (!ResultReg) 14720fca6ea1SDimitry Andric return false; 14730fca6ea1SDimitry Andric updateValueMap(II, ResultReg); 14740fca6ea1SDimitry Andric return true; 14750fca6ea1SDimitry Andric } 14760fca6ea1SDimitry Andric 14770b57cec5SDimitry Andric case Intrinsic::launder_invariant_group: 14780b57cec5SDimitry Andric case Intrinsic::strip_invariant_group: 14790b57cec5SDimitry Andric case Intrinsic::expect: { 14805ffd83dbSDimitry Andric Register ResultReg = getRegForValue(II->getArgOperand(0)); 14810b57cec5SDimitry Andric if (!ResultReg) 14820b57cec5SDimitry Andric return false; 14830b57cec5SDimitry Andric updateValueMap(II, ResultReg); 14840b57cec5SDimitry Andric return true; 14850b57cec5SDimitry Andric } 14860b57cec5SDimitry Andric case Intrinsic::experimental_stackmap: 14870b57cec5SDimitry Andric return selectStackmap(II); 14880b57cec5SDimitry Andric case Intrinsic::experimental_patchpoint_void: 14890fca6ea1SDimitry Andric case Intrinsic::experimental_patchpoint: 14900b57cec5SDimitry Andric return selectPatchpoint(II); 14910b57cec5SDimitry Andric 14920b57cec5SDimitry Andric case Intrinsic::xray_customevent: 14930b57cec5SDimitry Andric return selectXRayCustomEvent(II); 14940b57cec5SDimitry Andric case Intrinsic::xray_typedevent: 14950b57cec5SDimitry Andric return selectXRayTypedEvent(II); 14960b57cec5SDimitry Andric } 14970b57cec5SDimitry Andric 14980b57cec5SDimitry Andric return fastLowerIntrinsicCall(II); 14990b57cec5SDimitry Andric } 15000b57cec5SDimitry Andric 15010b57cec5SDimitry Andric bool FastISel::selectCast(const User *I, unsigned Opcode) { 15020b57cec5SDimitry Andric EVT SrcVT = TLI.getValueType(DL, I->getOperand(0)->getType()); 15030b57cec5SDimitry Andric EVT DstVT = TLI.getValueType(DL, I->getType()); 15040b57cec5SDimitry Andric 15050b57cec5SDimitry Andric if (SrcVT == MVT::Other || !SrcVT.isSimple() || DstVT == MVT::Other || 15060b57cec5SDimitry Andric !DstVT.isSimple()) 15070b57cec5SDimitry Andric // Unhandled type. Halt "fast" selection and bail. 15080b57cec5SDimitry Andric return false; 15090b57cec5SDimitry Andric 15100b57cec5SDimitry Andric // Check if the destination type is legal. 15110b57cec5SDimitry Andric if (!TLI.isTypeLegal(DstVT)) 15120b57cec5SDimitry Andric return false; 15130b57cec5SDimitry Andric 15140b57cec5SDimitry Andric // Check if the source operand is legal. 15150b57cec5SDimitry Andric if (!TLI.isTypeLegal(SrcVT)) 15160b57cec5SDimitry Andric return false; 15170b57cec5SDimitry Andric 15185ffd83dbSDimitry Andric Register InputReg = getRegForValue(I->getOperand(0)); 15190b57cec5SDimitry Andric if (!InputReg) 15200b57cec5SDimitry Andric // Unhandled operand. Halt "fast" selection and bail. 15210b57cec5SDimitry Andric return false; 15220b57cec5SDimitry Andric 15235ffd83dbSDimitry Andric Register ResultReg = fastEmit_r(SrcVT.getSimpleVT(), DstVT.getSimpleVT(), 1524fe6060f1SDimitry Andric Opcode, InputReg); 15250b57cec5SDimitry Andric if (!ResultReg) 15260b57cec5SDimitry Andric return false; 15270b57cec5SDimitry Andric 15280b57cec5SDimitry Andric updateValueMap(I, ResultReg); 15290b57cec5SDimitry Andric return true; 15300b57cec5SDimitry Andric } 15310b57cec5SDimitry Andric 15320b57cec5SDimitry Andric bool FastISel::selectBitCast(const User *I) { 15330b57cec5SDimitry Andric EVT SrcEVT = TLI.getValueType(DL, I->getOperand(0)->getType()); 15340b57cec5SDimitry Andric EVT DstEVT = TLI.getValueType(DL, I->getType()); 15350b57cec5SDimitry Andric if (SrcEVT == MVT::Other || DstEVT == MVT::Other || 15360b57cec5SDimitry Andric !TLI.isTypeLegal(SrcEVT) || !TLI.isTypeLegal(DstEVT)) 15370b57cec5SDimitry Andric // Unhandled type. Halt "fast" selection and bail. 15380b57cec5SDimitry Andric return false; 15390b57cec5SDimitry Andric 15400b57cec5SDimitry Andric MVT SrcVT = SrcEVT.getSimpleVT(); 15410b57cec5SDimitry Andric MVT DstVT = DstEVT.getSimpleVT(); 15425ffd83dbSDimitry Andric Register Op0 = getRegForValue(I->getOperand(0)); 15430b57cec5SDimitry Andric if (!Op0) // Unhandled operand. Halt "fast" selection and bail. 15440b57cec5SDimitry Andric return false; 15450b57cec5SDimitry Andric 154681ad6265SDimitry Andric // If the bitcast doesn't change the type, just use the operand value. 15470b57cec5SDimitry Andric if (SrcVT == DstVT) { 154881ad6265SDimitry Andric updateValueMap(I, Op0); 154981ad6265SDimitry Andric return true; 15500b57cec5SDimitry Andric } 15510b57cec5SDimitry Andric 155281ad6265SDimitry Andric // Otherwise, select a BITCAST opcode. 155381ad6265SDimitry Andric Register ResultReg = fastEmit_r(SrcVT, DstVT, ISD::BITCAST, Op0); 15540b57cec5SDimitry Andric if (!ResultReg) 15550b57cec5SDimitry Andric return false; 15560b57cec5SDimitry Andric 15570b57cec5SDimitry Andric updateValueMap(I, ResultReg); 15580b57cec5SDimitry Andric return true; 15590b57cec5SDimitry Andric } 15600b57cec5SDimitry Andric 15615ffd83dbSDimitry Andric bool FastISel::selectFreeze(const User *I) { 15625ffd83dbSDimitry Andric Register Reg = getRegForValue(I->getOperand(0)); 15635ffd83dbSDimitry Andric if (!Reg) 15645ffd83dbSDimitry Andric // Unhandled operand. 15655ffd83dbSDimitry Andric return false; 15665ffd83dbSDimitry Andric 15675ffd83dbSDimitry Andric EVT ETy = TLI.getValueType(DL, I->getOperand(0)->getType()); 15685ffd83dbSDimitry Andric if (ETy == MVT::Other || !TLI.isTypeLegal(ETy)) 15695ffd83dbSDimitry Andric // Unhandled type, bail out. 15705ffd83dbSDimitry Andric return false; 15715ffd83dbSDimitry Andric 15725ffd83dbSDimitry Andric MVT Ty = ETy.getSimpleVT(); 15735ffd83dbSDimitry Andric const TargetRegisterClass *TyRegClass = TLI.getRegClassFor(Ty); 15745ffd83dbSDimitry Andric Register ResultReg = createResultReg(TyRegClass); 1575bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, 15765ffd83dbSDimitry Andric TII.get(TargetOpcode::COPY), ResultReg).addReg(Reg); 15775ffd83dbSDimitry Andric 15785ffd83dbSDimitry Andric updateValueMap(I, ResultReg); 15795ffd83dbSDimitry Andric return true; 15805ffd83dbSDimitry Andric } 15815ffd83dbSDimitry Andric 15820b57cec5SDimitry Andric // Remove local value instructions starting from the instruction after 15830b57cec5SDimitry Andric // SavedLastLocalValue to the current function insert point. 15840b57cec5SDimitry Andric void FastISel::removeDeadLocalValueCode(MachineInstr *SavedLastLocalValue) 15850b57cec5SDimitry Andric { 15860b57cec5SDimitry Andric MachineInstr *CurLastLocalValue = getLastLocalValue(); 15870b57cec5SDimitry Andric if (CurLastLocalValue != SavedLastLocalValue) { 15880b57cec5SDimitry Andric // Find the first local value instruction to be deleted. 15890b57cec5SDimitry Andric // This is the instruction after SavedLastLocalValue if it is non-NULL. 15900b57cec5SDimitry Andric // Otherwise it's the first instruction in the block. 15910b57cec5SDimitry Andric MachineBasicBlock::iterator FirstDeadInst(SavedLastLocalValue); 15920b57cec5SDimitry Andric if (SavedLastLocalValue) 15930b57cec5SDimitry Andric ++FirstDeadInst; 15940b57cec5SDimitry Andric else 15950b57cec5SDimitry Andric FirstDeadInst = FuncInfo.MBB->getFirstNonPHI(); 15960b57cec5SDimitry Andric setLastLocalValue(SavedLastLocalValue); 15970b57cec5SDimitry Andric removeDeadCode(FirstDeadInst, FuncInfo.InsertPt); 15980b57cec5SDimitry Andric } 15990b57cec5SDimitry Andric } 16000b57cec5SDimitry Andric 16010b57cec5SDimitry Andric bool FastISel::selectInstruction(const Instruction *I) { 1602e8d8bef9SDimitry Andric // Flush the local value map before starting each instruction. 1603e8d8bef9SDimitry Andric // This improves locality and debugging, and can reduce spills. 1604e8d8bef9SDimitry Andric // Reuse of values across IR instructions is relatively uncommon. 1605e8d8bef9SDimitry Andric flushLocalValueMap(); 1606e8d8bef9SDimitry Andric 16070b57cec5SDimitry Andric MachineInstr *SavedLastLocalValue = getLastLocalValue(); 16080b57cec5SDimitry Andric // Just before the terminator instruction, insert instructions to 16090b57cec5SDimitry Andric // feed PHI nodes in successor blocks. 16100b57cec5SDimitry Andric if (I->isTerminator()) { 16110b57cec5SDimitry Andric if (!handlePHINodesInSuccessorBlocks(I->getParent())) { 16120b57cec5SDimitry Andric // PHI node handling may have generated local value instructions, 16130b57cec5SDimitry Andric // even though it failed to handle all PHI nodes. 16140b57cec5SDimitry Andric // We remove these instructions because SelectionDAGISel will generate 16150b57cec5SDimitry Andric // them again. 16160b57cec5SDimitry Andric removeDeadLocalValueCode(SavedLastLocalValue); 16170b57cec5SDimitry Andric return false; 16180b57cec5SDimitry Andric } 16190b57cec5SDimitry Andric } 16200b57cec5SDimitry Andric 16210b57cec5SDimitry Andric // FastISel does not handle any operand bundles except OB_funclet. 16225ffd83dbSDimitry Andric if (auto *Call = dyn_cast<CallBase>(I)) 16235ffd83dbSDimitry Andric for (unsigned i = 0, e = Call->getNumOperandBundles(); i != e; ++i) 16245ffd83dbSDimitry Andric if (Call->getOperandBundleAt(i).getTagID() != LLVMContext::OB_funclet) 16250b57cec5SDimitry Andric return false; 16260b57cec5SDimitry Andric 1627bdd1243dSDimitry Andric MIMD = MIMetadata(*I); 16280b57cec5SDimitry Andric 16290b57cec5SDimitry Andric SavedInsertPt = FuncInfo.InsertPt; 16300b57cec5SDimitry Andric 16310b57cec5SDimitry Andric if (const auto *Call = dyn_cast<CallInst>(I)) { 16320b57cec5SDimitry Andric const Function *F = Call->getCalledFunction(); 16330b57cec5SDimitry Andric LibFunc Func; 16340b57cec5SDimitry Andric 16350b57cec5SDimitry Andric // As a special case, don't handle calls to builtin library functions that 16360b57cec5SDimitry Andric // may be translated directly to target instructions. 16370b57cec5SDimitry Andric if (F && !F->hasLocalLinkage() && F->hasName() && 16380b57cec5SDimitry Andric LibInfo->getLibFunc(F->getName(), Func) && 16390b57cec5SDimitry Andric LibInfo->hasOptimizedCodeGen(Func)) 16400b57cec5SDimitry Andric return false; 16410b57cec5SDimitry Andric 16420b57cec5SDimitry Andric // Don't handle Intrinsic::trap if a trap function is specified. 16430b57cec5SDimitry Andric if (F && F->getIntrinsicID() == Intrinsic::trap && 16440b57cec5SDimitry Andric Call->hasFnAttr("trap-func-name")) 16450b57cec5SDimitry Andric return false; 16460b57cec5SDimitry Andric } 16470b57cec5SDimitry Andric 16480b57cec5SDimitry Andric // First, try doing target-independent selection. 16490b57cec5SDimitry Andric if (!SkipTargetIndependentISel) { 16500b57cec5SDimitry Andric if (selectOperator(I, I->getOpcode())) { 16510b57cec5SDimitry Andric ++NumFastIselSuccessIndependent; 1652bdd1243dSDimitry Andric MIMD = {}; 16530b57cec5SDimitry Andric return true; 16540b57cec5SDimitry Andric } 16550b57cec5SDimitry Andric // Remove dead code. 16560b57cec5SDimitry Andric recomputeInsertPt(); 16570b57cec5SDimitry Andric if (SavedInsertPt != FuncInfo.InsertPt) 16580b57cec5SDimitry Andric removeDeadCode(FuncInfo.InsertPt, SavedInsertPt); 16590b57cec5SDimitry Andric SavedInsertPt = FuncInfo.InsertPt; 16600b57cec5SDimitry Andric } 16610b57cec5SDimitry Andric // Next, try calling the target to attempt to handle the instruction. 16620b57cec5SDimitry Andric if (fastSelectInstruction(I)) { 16630b57cec5SDimitry Andric ++NumFastIselSuccessTarget; 1664bdd1243dSDimitry Andric MIMD = {}; 16650b57cec5SDimitry Andric return true; 16660b57cec5SDimitry Andric } 16670b57cec5SDimitry Andric // Remove dead code. 16680b57cec5SDimitry Andric recomputeInsertPt(); 16690b57cec5SDimitry Andric if (SavedInsertPt != FuncInfo.InsertPt) 16700b57cec5SDimitry Andric removeDeadCode(FuncInfo.InsertPt, SavedInsertPt); 16710b57cec5SDimitry Andric 1672bdd1243dSDimitry Andric MIMD = {}; 16730b57cec5SDimitry Andric // Undo phi node updates, because they will be added again by SelectionDAG. 16740b57cec5SDimitry Andric if (I->isTerminator()) { 16750b57cec5SDimitry Andric // PHI node handling may have generated local value instructions. 16760b57cec5SDimitry Andric // We remove them because SelectionDAGISel will generate them again. 16770b57cec5SDimitry Andric removeDeadLocalValueCode(SavedLastLocalValue); 16780b57cec5SDimitry Andric FuncInfo.PHINodesToUpdate.resize(FuncInfo.OrigNumPHINodesToUpdate); 16790b57cec5SDimitry Andric } 16800b57cec5SDimitry Andric return false; 16810b57cec5SDimitry Andric } 16820b57cec5SDimitry Andric 16830b57cec5SDimitry Andric /// Emit an unconditional branch to the given block, unless it is the immediate 16840b57cec5SDimitry Andric /// (fall-through) successor, and update the CFG. 16850b57cec5SDimitry Andric void FastISel::fastEmitBranch(MachineBasicBlock *MSucc, 16860b57cec5SDimitry Andric const DebugLoc &DbgLoc) { 16878bcb0991SDimitry Andric if (FuncInfo.MBB->getBasicBlock()->sizeWithoutDebug() > 1 && 16880b57cec5SDimitry Andric FuncInfo.MBB->isLayoutSuccessor(MSucc)) { 16898bcb0991SDimitry Andric // For more accurate line information if this is the only non-debug 16908bcb0991SDimitry Andric // instruction in the block then emit it, otherwise we have the 16918bcb0991SDimitry Andric // unconditional fall-through case, which needs no instructions. 16920b57cec5SDimitry Andric } else { 16930b57cec5SDimitry Andric // The unconditional branch case. 16940b57cec5SDimitry Andric TII.insertBranch(*FuncInfo.MBB, MSucc, nullptr, 16950b57cec5SDimitry Andric SmallVector<MachineOperand, 0>(), DbgLoc); 16960b57cec5SDimitry Andric } 16970b57cec5SDimitry Andric if (FuncInfo.BPI) { 16980b57cec5SDimitry Andric auto BranchProbability = FuncInfo.BPI->getEdgeProbability( 16990b57cec5SDimitry Andric FuncInfo.MBB->getBasicBlock(), MSucc->getBasicBlock()); 17000b57cec5SDimitry Andric FuncInfo.MBB->addSuccessor(MSucc, BranchProbability); 17010b57cec5SDimitry Andric } else 17020b57cec5SDimitry Andric FuncInfo.MBB->addSuccessorWithoutProb(MSucc); 17030b57cec5SDimitry Andric } 17040b57cec5SDimitry Andric 17050b57cec5SDimitry Andric void FastISel::finishCondBranch(const BasicBlock *BranchBB, 17060b57cec5SDimitry Andric MachineBasicBlock *TrueMBB, 17070b57cec5SDimitry Andric MachineBasicBlock *FalseMBB) { 17080b57cec5SDimitry Andric // Add TrueMBB as successor unless it is equal to the FalseMBB: This can 17090b57cec5SDimitry Andric // happen in degenerate IR and MachineIR forbids to have a block twice in the 17100b57cec5SDimitry Andric // successor/predecessor lists. 17110b57cec5SDimitry Andric if (TrueMBB != FalseMBB) { 17120b57cec5SDimitry Andric if (FuncInfo.BPI) { 17130b57cec5SDimitry Andric auto BranchProbability = 17140b57cec5SDimitry Andric FuncInfo.BPI->getEdgeProbability(BranchBB, TrueMBB->getBasicBlock()); 17150b57cec5SDimitry Andric FuncInfo.MBB->addSuccessor(TrueMBB, BranchProbability); 17160b57cec5SDimitry Andric } else 17170b57cec5SDimitry Andric FuncInfo.MBB->addSuccessorWithoutProb(TrueMBB); 17180b57cec5SDimitry Andric } 17190b57cec5SDimitry Andric 1720bdd1243dSDimitry Andric fastEmitBranch(FalseMBB, MIMD.getDL()); 17210b57cec5SDimitry Andric } 17220b57cec5SDimitry Andric 17230b57cec5SDimitry Andric /// Emit an FNeg operation. 17240b57cec5SDimitry Andric bool FastISel::selectFNeg(const User *I, const Value *In) { 17255ffd83dbSDimitry Andric Register OpReg = getRegForValue(In); 17260b57cec5SDimitry Andric if (!OpReg) 17270b57cec5SDimitry Andric return false; 17280b57cec5SDimitry Andric 17290b57cec5SDimitry Andric // If the target has ISD::FNEG, use it. 17300b57cec5SDimitry Andric EVT VT = TLI.getValueType(DL, I->getType()); 17315ffd83dbSDimitry Andric Register ResultReg = fastEmit_r(VT.getSimpleVT(), VT.getSimpleVT(), ISD::FNEG, 1732fe6060f1SDimitry Andric OpReg); 17330b57cec5SDimitry Andric if (ResultReg) { 17340b57cec5SDimitry Andric updateValueMap(I, ResultReg); 17350b57cec5SDimitry Andric return true; 17360b57cec5SDimitry Andric } 17370b57cec5SDimitry Andric 17380b57cec5SDimitry Andric // Bitcast the value to integer, twiddle the sign bit with xor, 17390b57cec5SDimitry Andric // and then bitcast it back to floating-point. 17400b57cec5SDimitry Andric if (VT.getSizeInBits() > 64) 17410b57cec5SDimitry Andric return false; 17420b57cec5SDimitry Andric EVT IntVT = EVT::getIntegerVT(I->getContext(), VT.getSizeInBits()); 17430b57cec5SDimitry Andric if (!TLI.isTypeLegal(IntVT)) 17440b57cec5SDimitry Andric return false; 17450b57cec5SDimitry Andric 17465ffd83dbSDimitry Andric Register IntReg = fastEmit_r(VT.getSimpleVT(), IntVT.getSimpleVT(), 1747fe6060f1SDimitry Andric ISD::BITCAST, OpReg); 17480b57cec5SDimitry Andric if (!IntReg) 17490b57cec5SDimitry Andric return false; 17500b57cec5SDimitry Andric 17515ffd83dbSDimitry Andric Register IntResultReg = fastEmit_ri_( 1752fe6060f1SDimitry Andric IntVT.getSimpleVT(), ISD::XOR, IntReg, 17530b57cec5SDimitry Andric UINT64_C(1) << (VT.getSizeInBits() - 1), IntVT.getSimpleVT()); 17540b57cec5SDimitry Andric if (!IntResultReg) 17550b57cec5SDimitry Andric return false; 17560b57cec5SDimitry Andric 17570b57cec5SDimitry Andric ResultReg = fastEmit_r(IntVT.getSimpleVT(), VT.getSimpleVT(), ISD::BITCAST, 1758fe6060f1SDimitry Andric IntResultReg); 17590b57cec5SDimitry Andric if (!ResultReg) 17600b57cec5SDimitry Andric return false; 17610b57cec5SDimitry Andric 17620b57cec5SDimitry Andric updateValueMap(I, ResultReg); 17630b57cec5SDimitry Andric return true; 17640b57cec5SDimitry Andric } 17650b57cec5SDimitry Andric 17660b57cec5SDimitry Andric bool FastISel::selectExtractValue(const User *U) { 17670b57cec5SDimitry Andric const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(U); 17680b57cec5SDimitry Andric if (!EVI) 17690b57cec5SDimitry Andric return false; 17700b57cec5SDimitry Andric 17710b57cec5SDimitry Andric // Make sure we only try to handle extracts with a legal result. But also 17720b57cec5SDimitry Andric // allow i1 because it's easy. 17730b57cec5SDimitry Andric EVT RealVT = TLI.getValueType(DL, EVI->getType(), /*AllowUnknown=*/true); 17740b57cec5SDimitry Andric if (!RealVT.isSimple()) 17750b57cec5SDimitry Andric return false; 17760b57cec5SDimitry Andric MVT VT = RealVT.getSimpleVT(); 17770b57cec5SDimitry Andric if (!TLI.isTypeLegal(VT) && VT != MVT::i1) 17780b57cec5SDimitry Andric return false; 17790b57cec5SDimitry Andric 17800b57cec5SDimitry Andric const Value *Op0 = EVI->getOperand(0); 17810b57cec5SDimitry Andric Type *AggTy = Op0->getType(); 17820b57cec5SDimitry Andric 17830b57cec5SDimitry Andric // Get the base result register. 17840b57cec5SDimitry Andric unsigned ResultReg; 17855ffd83dbSDimitry Andric DenseMap<const Value *, Register>::iterator I = FuncInfo.ValueMap.find(Op0); 17860b57cec5SDimitry Andric if (I != FuncInfo.ValueMap.end()) 17870b57cec5SDimitry Andric ResultReg = I->second; 17880b57cec5SDimitry Andric else if (isa<Instruction>(Op0)) 17890b57cec5SDimitry Andric ResultReg = FuncInfo.InitializeRegForValue(Op0); 17900b57cec5SDimitry Andric else 17910b57cec5SDimitry Andric return false; // fast-isel can't handle aggregate constants at the moment 17920b57cec5SDimitry Andric 17930b57cec5SDimitry Andric // Get the actual result register, which is an offset from the base register. 17940b57cec5SDimitry Andric unsigned VTIndex = ComputeLinearIndex(AggTy, EVI->getIndices()); 17950b57cec5SDimitry Andric 17960b57cec5SDimitry Andric SmallVector<EVT, 4> AggValueVTs; 17970b57cec5SDimitry Andric ComputeValueVTs(TLI, DL, AggTy, AggValueVTs); 17980b57cec5SDimitry Andric 17990b57cec5SDimitry Andric for (unsigned i = 0; i < VTIndex; i++) 18000b57cec5SDimitry Andric ResultReg += TLI.getNumRegisters(FuncInfo.Fn->getContext(), AggValueVTs[i]); 18010b57cec5SDimitry Andric 18020b57cec5SDimitry Andric updateValueMap(EVI, ResultReg); 18030b57cec5SDimitry Andric return true; 18040b57cec5SDimitry Andric } 18050b57cec5SDimitry Andric 18060b57cec5SDimitry Andric bool FastISel::selectOperator(const User *I, unsigned Opcode) { 18070b57cec5SDimitry Andric switch (Opcode) { 18080b57cec5SDimitry Andric case Instruction::Add: 18090b57cec5SDimitry Andric return selectBinaryOp(I, ISD::ADD); 18100b57cec5SDimitry Andric case Instruction::FAdd: 18110b57cec5SDimitry Andric return selectBinaryOp(I, ISD::FADD); 18120b57cec5SDimitry Andric case Instruction::Sub: 18130b57cec5SDimitry Andric return selectBinaryOp(I, ISD::SUB); 1814e8d8bef9SDimitry Andric case Instruction::FSub: 18150b57cec5SDimitry Andric return selectBinaryOp(I, ISD::FSUB); 18160b57cec5SDimitry Andric case Instruction::Mul: 18170b57cec5SDimitry Andric return selectBinaryOp(I, ISD::MUL); 18180b57cec5SDimitry Andric case Instruction::FMul: 18190b57cec5SDimitry Andric return selectBinaryOp(I, ISD::FMUL); 18200b57cec5SDimitry Andric case Instruction::SDiv: 18210b57cec5SDimitry Andric return selectBinaryOp(I, ISD::SDIV); 18220b57cec5SDimitry Andric case Instruction::UDiv: 18230b57cec5SDimitry Andric return selectBinaryOp(I, ISD::UDIV); 18240b57cec5SDimitry Andric case Instruction::FDiv: 18250b57cec5SDimitry Andric return selectBinaryOp(I, ISD::FDIV); 18260b57cec5SDimitry Andric case Instruction::SRem: 18270b57cec5SDimitry Andric return selectBinaryOp(I, ISD::SREM); 18280b57cec5SDimitry Andric case Instruction::URem: 18290b57cec5SDimitry Andric return selectBinaryOp(I, ISD::UREM); 18300b57cec5SDimitry Andric case Instruction::FRem: 18310b57cec5SDimitry Andric return selectBinaryOp(I, ISD::FREM); 18320b57cec5SDimitry Andric case Instruction::Shl: 18330b57cec5SDimitry Andric return selectBinaryOp(I, ISD::SHL); 18340b57cec5SDimitry Andric case Instruction::LShr: 18350b57cec5SDimitry Andric return selectBinaryOp(I, ISD::SRL); 18360b57cec5SDimitry Andric case Instruction::AShr: 18370b57cec5SDimitry Andric return selectBinaryOp(I, ISD::SRA); 18380b57cec5SDimitry Andric case Instruction::And: 18390b57cec5SDimitry Andric return selectBinaryOp(I, ISD::AND); 18400b57cec5SDimitry Andric case Instruction::Or: 18410b57cec5SDimitry Andric return selectBinaryOp(I, ISD::OR); 18420b57cec5SDimitry Andric case Instruction::Xor: 18430b57cec5SDimitry Andric return selectBinaryOp(I, ISD::XOR); 18440b57cec5SDimitry Andric 18450b57cec5SDimitry Andric case Instruction::FNeg: 18460b57cec5SDimitry Andric return selectFNeg(I, I->getOperand(0)); 18470b57cec5SDimitry Andric 18480b57cec5SDimitry Andric case Instruction::GetElementPtr: 18490b57cec5SDimitry Andric return selectGetElementPtr(I); 18500b57cec5SDimitry Andric 18510b57cec5SDimitry Andric case Instruction::Br: { 18520b57cec5SDimitry Andric const BranchInst *BI = cast<BranchInst>(I); 18530b57cec5SDimitry Andric 18540b57cec5SDimitry Andric if (BI->isUnconditional()) { 18550b57cec5SDimitry Andric const BasicBlock *LLVMSucc = BI->getSuccessor(0); 18560b57cec5SDimitry Andric MachineBasicBlock *MSucc = FuncInfo.MBBMap[LLVMSucc]; 18570b57cec5SDimitry Andric fastEmitBranch(MSucc, BI->getDebugLoc()); 18580b57cec5SDimitry Andric return true; 18590b57cec5SDimitry Andric } 18600b57cec5SDimitry Andric 18610b57cec5SDimitry Andric // Conditional branches are not handed yet. 18620b57cec5SDimitry Andric // Halt "fast" selection and bail. 18630b57cec5SDimitry Andric return false; 18640b57cec5SDimitry Andric } 18650b57cec5SDimitry Andric 18660b57cec5SDimitry Andric case Instruction::Unreachable: 18670b57cec5SDimitry Andric if (TM.Options.TrapUnreachable) 18680b57cec5SDimitry Andric return fastEmit_(MVT::Other, MVT::Other, ISD::TRAP) != 0; 18690b57cec5SDimitry Andric else 18700b57cec5SDimitry Andric return true; 18710b57cec5SDimitry Andric 18720b57cec5SDimitry Andric case Instruction::Alloca: 18730b57cec5SDimitry Andric // FunctionLowering has the static-sized case covered. 18740b57cec5SDimitry Andric if (FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(I))) 18750b57cec5SDimitry Andric return true; 18760b57cec5SDimitry Andric 18770b57cec5SDimitry Andric // Dynamic-sized alloca is not handled yet. 18780b57cec5SDimitry Andric return false; 18790b57cec5SDimitry Andric 18800b57cec5SDimitry Andric case Instruction::Call: 188104eeddc0SDimitry Andric // On AIX, normal call lowering uses the DAG-ISEL path currently so that the 18820b57cec5SDimitry Andric // callee of the direct function call instruction will be mapped to the 18830b57cec5SDimitry Andric // symbol for the function's entry point, which is distinct from the 18840b57cec5SDimitry Andric // function descriptor symbol. The latter is the symbol whose XCOFF symbol 18850b57cec5SDimitry Andric // name is the C-linkage name of the source level function. 188604eeddc0SDimitry Andric // But fast isel still has the ability to do selection for intrinsics. 188704eeddc0SDimitry Andric if (TM.getTargetTriple().isOSAIX() && !isa<IntrinsicInst>(I)) 18880b57cec5SDimitry Andric return false; 18890b57cec5SDimitry Andric return selectCall(I); 18900b57cec5SDimitry Andric 18910b57cec5SDimitry Andric case Instruction::BitCast: 18920b57cec5SDimitry Andric return selectBitCast(I); 18930b57cec5SDimitry Andric 18940b57cec5SDimitry Andric case Instruction::FPToSI: 18950b57cec5SDimitry Andric return selectCast(I, ISD::FP_TO_SINT); 18960b57cec5SDimitry Andric case Instruction::ZExt: 18970b57cec5SDimitry Andric return selectCast(I, ISD::ZERO_EXTEND); 18980b57cec5SDimitry Andric case Instruction::SExt: 18990b57cec5SDimitry Andric return selectCast(I, ISD::SIGN_EXTEND); 19000b57cec5SDimitry Andric case Instruction::Trunc: 19010b57cec5SDimitry Andric return selectCast(I, ISD::TRUNCATE); 19020b57cec5SDimitry Andric case Instruction::SIToFP: 19030b57cec5SDimitry Andric return selectCast(I, ISD::SINT_TO_FP); 19040b57cec5SDimitry Andric 19050b57cec5SDimitry Andric case Instruction::IntToPtr: // Deliberate fall-through. 19060b57cec5SDimitry Andric case Instruction::PtrToInt: { 19070b57cec5SDimitry Andric EVT SrcVT = TLI.getValueType(DL, I->getOperand(0)->getType()); 19080b57cec5SDimitry Andric EVT DstVT = TLI.getValueType(DL, I->getType()); 19090b57cec5SDimitry Andric if (DstVT.bitsGT(SrcVT)) 19100b57cec5SDimitry Andric return selectCast(I, ISD::ZERO_EXTEND); 19110b57cec5SDimitry Andric if (DstVT.bitsLT(SrcVT)) 19120b57cec5SDimitry Andric return selectCast(I, ISD::TRUNCATE); 19135ffd83dbSDimitry Andric Register Reg = getRegForValue(I->getOperand(0)); 19140b57cec5SDimitry Andric if (!Reg) 19150b57cec5SDimitry Andric return false; 19160b57cec5SDimitry Andric updateValueMap(I, Reg); 19170b57cec5SDimitry Andric return true; 19180b57cec5SDimitry Andric } 19190b57cec5SDimitry Andric 19200b57cec5SDimitry Andric case Instruction::ExtractValue: 19210b57cec5SDimitry Andric return selectExtractValue(I); 19220b57cec5SDimitry Andric 19235ffd83dbSDimitry Andric case Instruction::Freeze: 19245ffd83dbSDimitry Andric return selectFreeze(I); 19255ffd83dbSDimitry Andric 19260b57cec5SDimitry Andric case Instruction::PHI: 19270b57cec5SDimitry Andric llvm_unreachable("FastISel shouldn't visit PHI nodes!"); 19280b57cec5SDimitry Andric 19290b57cec5SDimitry Andric default: 19300b57cec5SDimitry Andric // Unhandled instruction. Halt "fast" selection and bail. 19310b57cec5SDimitry Andric return false; 19320b57cec5SDimitry Andric } 19330b57cec5SDimitry Andric } 19340b57cec5SDimitry Andric 19350b57cec5SDimitry Andric FastISel::FastISel(FunctionLoweringInfo &FuncInfo, 19360b57cec5SDimitry Andric const TargetLibraryInfo *LibInfo, 19370b57cec5SDimitry Andric bool SkipTargetIndependentISel) 19380b57cec5SDimitry Andric : FuncInfo(FuncInfo), MF(FuncInfo.MF), MRI(FuncInfo.MF->getRegInfo()), 19390b57cec5SDimitry Andric MFI(FuncInfo.MF->getFrameInfo()), MCP(*FuncInfo.MF->getConstantPool()), 19400b57cec5SDimitry Andric TM(FuncInfo.MF->getTarget()), DL(MF->getDataLayout()), 19410b57cec5SDimitry Andric TII(*MF->getSubtarget().getInstrInfo()), 19420b57cec5SDimitry Andric TLI(*MF->getSubtarget().getTargetLowering()), 19430b57cec5SDimitry Andric TRI(*MF->getSubtarget().getRegisterInfo()), LibInfo(LibInfo), 19441fd87a68SDimitry Andric SkipTargetIndependentISel(SkipTargetIndependentISel) {} 19450b57cec5SDimitry Andric 19460b57cec5SDimitry Andric FastISel::~FastISel() = default; 19470b57cec5SDimitry Andric 19480b57cec5SDimitry Andric bool FastISel::fastLowerArguments() { return false; } 19490b57cec5SDimitry Andric 19500b57cec5SDimitry Andric bool FastISel::fastLowerCall(CallLoweringInfo & /*CLI*/) { return false; } 19510b57cec5SDimitry Andric 19520b57cec5SDimitry Andric bool FastISel::fastLowerIntrinsicCall(const IntrinsicInst * /*II*/) { 19530b57cec5SDimitry Andric return false; 19540b57cec5SDimitry Andric } 19550b57cec5SDimitry Andric 19560b57cec5SDimitry Andric unsigned FastISel::fastEmit_(MVT, MVT, unsigned) { return 0; } 19570b57cec5SDimitry Andric 1958fe6060f1SDimitry Andric unsigned FastISel::fastEmit_r(MVT, MVT, unsigned, unsigned /*Op0*/) { 19590b57cec5SDimitry Andric return 0; 19600b57cec5SDimitry Andric } 19610b57cec5SDimitry Andric 19620b57cec5SDimitry Andric unsigned FastISel::fastEmit_rr(MVT, MVT, unsigned, unsigned /*Op0*/, 1963fe6060f1SDimitry Andric unsigned /*Op1*/) { 19640b57cec5SDimitry Andric return 0; 19650b57cec5SDimitry Andric } 19660b57cec5SDimitry Andric 19670b57cec5SDimitry Andric unsigned FastISel::fastEmit_i(MVT, MVT, unsigned, uint64_t /*Imm*/) { 19680b57cec5SDimitry Andric return 0; 19690b57cec5SDimitry Andric } 19700b57cec5SDimitry Andric 19710b57cec5SDimitry Andric unsigned FastISel::fastEmit_f(MVT, MVT, unsigned, 19720b57cec5SDimitry Andric const ConstantFP * /*FPImm*/) { 19730b57cec5SDimitry Andric return 0; 19740b57cec5SDimitry Andric } 19750b57cec5SDimitry Andric 19760b57cec5SDimitry Andric unsigned FastISel::fastEmit_ri(MVT, MVT, unsigned, unsigned /*Op0*/, 1977fe6060f1SDimitry Andric uint64_t /*Imm*/) { 19780b57cec5SDimitry Andric return 0; 19790b57cec5SDimitry Andric } 19800b57cec5SDimitry Andric 19810b57cec5SDimitry Andric /// This method is a wrapper of fastEmit_ri. It first tries to emit an 19820b57cec5SDimitry Andric /// instruction with an immediate operand using fastEmit_ri. 19830b57cec5SDimitry Andric /// If that fails, it materializes the immediate into a register and try 19840b57cec5SDimitry Andric /// fastEmit_rr instead. 19855ffd83dbSDimitry Andric Register FastISel::fastEmit_ri_(MVT VT, unsigned Opcode, unsigned Op0, 1986fe6060f1SDimitry Andric uint64_t Imm, MVT ImmType) { 19870b57cec5SDimitry Andric // If this is a multiply by a power of two, emit this as a shift left. 19880b57cec5SDimitry Andric if (Opcode == ISD::MUL && isPowerOf2_64(Imm)) { 19890b57cec5SDimitry Andric Opcode = ISD::SHL; 19900b57cec5SDimitry Andric Imm = Log2_64(Imm); 19910b57cec5SDimitry Andric } else if (Opcode == ISD::UDIV && isPowerOf2_64(Imm)) { 19920b57cec5SDimitry Andric // div x, 8 -> srl x, 3 19930b57cec5SDimitry Andric Opcode = ISD::SRL; 19940b57cec5SDimitry Andric Imm = Log2_64(Imm); 19950b57cec5SDimitry Andric } 19960b57cec5SDimitry Andric 19970b57cec5SDimitry Andric // Horrible hack (to be removed), check to make sure shift amounts are 19980b57cec5SDimitry Andric // in-range. 19990b57cec5SDimitry Andric if ((Opcode == ISD::SHL || Opcode == ISD::SRA || Opcode == ISD::SRL) && 20000b57cec5SDimitry Andric Imm >= VT.getSizeInBits()) 20010b57cec5SDimitry Andric return 0; 20020b57cec5SDimitry Andric 20030b57cec5SDimitry Andric // First check if immediate type is legal. If not, we can't use the ri form. 2004fe6060f1SDimitry Andric Register ResultReg = fastEmit_ri(VT, VT, Opcode, Op0, Imm); 20050b57cec5SDimitry Andric if (ResultReg) 20060b57cec5SDimitry Andric return ResultReg; 20075ffd83dbSDimitry Andric Register MaterialReg = fastEmit_i(ImmType, ImmType, ISD::Constant, Imm); 20080b57cec5SDimitry Andric if (!MaterialReg) { 20090b57cec5SDimitry Andric // This is a bit ugly/slow, but failing here means falling out of 20100b57cec5SDimitry Andric // fast-isel, which would be very slow. 20110b57cec5SDimitry Andric IntegerType *ITy = 20120b57cec5SDimitry Andric IntegerType::get(FuncInfo.Fn->getContext(), VT.getSizeInBits()); 20130b57cec5SDimitry Andric MaterialReg = getRegForValue(ConstantInt::get(ITy, Imm)); 20140b57cec5SDimitry Andric if (!MaterialReg) 20150b57cec5SDimitry Andric return 0; 20160b57cec5SDimitry Andric } 2017fe6060f1SDimitry Andric return fastEmit_rr(VT, VT, Opcode, Op0, MaterialReg); 20180b57cec5SDimitry Andric } 20190b57cec5SDimitry Andric 20205ffd83dbSDimitry Andric Register FastISel::createResultReg(const TargetRegisterClass *RC) { 20210b57cec5SDimitry Andric return MRI.createVirtualRegister(RC); 20220b57cec5SDimitry Andric } 20230b57cec5SDimitry Andric 20245ffd83dbSDimitry Andric Register FastISel::constrainOperandRegClass(const MCInstrDesc &II, Register Op, 20250b57cec5SDimitry Andric unsigned OpNum) { 20265ffd83dbSDimitry Andric if (Op.isVirtual()) { 20270b57cec5SDimitry Andric const TargetRegisterClass *RegClass = 20280b57cec5SDimitry Andric TII.getRegClass(II, OpNum, &TRI, *FuncInfo.MF); 20290b57cec5SDimitry Andric if (!MRI.constrainRegClass(Op, RegClass)) { 20300b57cec5SDimitry Andric // If it's not legal to COPY between the register classes, something 20310b57cec5SDimitry Andric // has gone very wrong before we got here. 20325ffd83dbSDimitry Andric Register NewOp = createResultReg(RegClass); 2033bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, 20340b57cec5SDimitry Andric TII.get(TargetOpcode::COPY), NewOp).addReg(Op); 20350b57cec5SDimitry Andric return NewOp; 20360b57cec5SDimitry Andric } 20370b57cec5SDimitry Andric } 20380b57cec5SDimitry Andric return Op; 20390b57cec5SDimitry Andric } 20400b57cec5SDimitry Andric 20415ffd83dbSDimitry Andric Register FastISel::fastEmitInst_(unsigned MachineInstOpcode, 20420b57cec5SDimitry Andric const TargetRegisterClass *RC) { 20435ffd83dbSDimitry Andric Register ResultReg = createResultReg(RC); 20440b57cec5SDimitry Andric const MCInstrDesc &II = TII.get(MachineInstOpcode); 20450b57cec5SDimitry Andric 2046bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg); 20470b57cec5SDimitry Andric return ResultReg; 20480b57cec5SDimitry Andric } 20490b57cec5SDimitry Andric 20505ffd83dbSDimitry Andric Register FastISel::fastEmitInst_r(unsigned MachineInstOpcode, 2051fe6060f1SDimitry Andric const TargetRegisterClass *RC, unsigned Op0) { 20520b57cec5SDimitry Andric const MCInstrDesc &II = TII.get(MachineInstOpcode); 20530b57cec5SDimitry Andric 20545ffd83dbSDimitry Andric Register ResultReg = createResultReg(RC); 20550b57cec5SDimitry Andric Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs()); 20560b57cec5SDimitry Andric 20570b57cec5SDimitry Andric if (II.getNumDefs() >= 1) 2058bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg) 2059fe6060f1SDimitry Andric .addReg(Op0); 20600b57cec5SDimitry Andric else { 2061bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II) 2062fe6060f1SDimitry Andric .addReg(Op0); 2063bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), 2064bdd1243dSDimitry Andric ResultReg) 2065bdd1243dSDimitry Andric .addReg(II.implicit_defs()[0]); 20660b57cec5SDimitry Andric } 20670b57cec5SDimitry Andric 20680b57cec5SDimitry Andric return ResultReg; 20690b57cec5SDimitry Andric } 20700b57cec5SDimitry Andric 20715ffd83dbSDimitry Andric Register FastISel::fastEmitInst_rr(unsigned MachineInstOpcode, 20720b57cec5SDimitry Andric const TargetRegisterClass *RC, unsigned Op0, 2073fe6060f1SDimitry Andric unsigned Op1) { 20740b57cec5SDimitry Andric const MCInstrDesc &II = TII.get(MachineInstOpcode); 20750b57cec5SDimitry Andric 20765ffd83dbSDimitry Andric Register ResultReg = createResultReg(RC); 20770b57cec5SDimitry Andric Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs()); 20780b57cec5SDimitry Andric Op1 = constrainOperandRegClass(II, Op1, II.getNumDefs() + 1); 20790b57cec5SDimitry Andric 20800b57cec5SDimitry Andric if (II.getNumDefs() >= 1) 2081bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg) 2082fe6060f1SDimitry Andric .addReg(Op0) 2083fe6060f1SDimitry Andric .addReg(Op1); 20840b57cec5SDimitry Andric else { 2085bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II) 2086fe6060f1SDimitry Andric .addReg(Op0) 2087fe6060f1SDimitry Andric .addReg(Op1); 2088bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), 2089bdd1243dSDimitry Andric ResultReg) 2090bdd1243dSDimitry Andric .addReg(II.implicit_defs()[0]); 20910b57cec5SDimitry Andric } 20920b57cec5SDimitry Andric return ResultReg; 20930b57cec5SDimitry Andric } 20940b57cec5SDimitry Andric 20955ffd83dbSDimitry Andric Register FastISel::fastEmitInst_rrr(unsigned MachineInstOpcode, 20960b57cec5SDimitry Andric const TargetRegisterClass *RC, unsigned Op0, 2097fe6060f1SDimitry Andric unsigned Op1, unsigned Op2) { 20980b57cec5SDimitry Andric const MCInstrDesc &II = TII.get(MachineInstOpcode); 20990b57cec5SDimitry Andric 21005ffd83dbSDimitry Andric Register ResultReg = createResultReg(RC); 21010b57cec5SDimitry Andric Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs()); 21020b57cec5SDimitry Andric Op1 = constrainOperandRegClass(II, Op1, II.getNumDefs() + 1); 21030b57cec5SDimitry Andric Op2 = constrainOperandRegClass(II, Op2, II.getNumDefs() + 2); 21040b57cec5SDimitry Andric 21050b57cec5SDimitry Andric if (II.getNumDefs() >= 1) 2106bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg) 2107fe6060f1SDimitry Andric .addReg(Op0) 2108fe6060f1SDimitry Andric .addReg(Op1) 2109fe6060f1SDimitry Andric .addReg(Op2); 21100b57cec5SDimitry Andric else { 2111bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II) 2112fe6060f1SDimitry Andric .addReg(Op0) 2113fe6060f1SDimitry Andric .addReg(Op1) 2114fe6060f1SDimitry Andric .addReg(Op2); 2115bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), 2116bdd1243dSDimitry Andric ResultReg) 2117bdd1243dSDimitry Andric .addReg(II.implicit_defs()[0]); 21180b57cec5SDimitry Andric } 21190b57cec5SDimitry Andric return ResultReg; 21200b57cec5SDimitry Andric } 21210b57cec5SDimitry Andric 21225ffd83dbSDimitry Andric Register FastISel::fastEmitInst_ri(unsigned MachineInstOpcode, 21230b57cec5SDimitry Andric const TargetRegisterClass *RC, unsigned Op0, 2124fe6060f1SDimitry Andric uint64_t Imm) { 21250b57cec5SDimitry Andric const MCInstrDesc &II = TII.get(MachineInstOpcode); 21260b57cec5SDimitry Andric 21275ffd83dbSDimitry Andric Register ResultReg = createResultReg(RC); 21280b57cec5SDimitry Andric Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs()); 21290b57cec5SDimitry Andric 21300b57cec5SDimitry Andric if (II.getNumDefs() >= 1) 2131bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg) 2132fe6060f1SDimitry Andric .addReg(Op0) 21330b57cec5SDimitry Andric .addImm(Imm); 21340b57cec5SDimitry Andric else { 2135bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II) 2136fe6060f1SDimitry Andric .addReg(Op0) 21370b57cec5SDimitry Andric .addImm(Imm); 2138bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), 2139bdd1243dSDimitry Andric ResultReg) 2140bdd1243dSDimitry Andric .addReg(II.implicit_defs()[0]); 21410b57cec5SDimitry Andric } 21420b57cec5SDimitry Andric return ResultReg; 21430b57cec5SDimitry Andric } 21440b57cec5SDimitry Andric 21455ffd83dbSDimitry Andric Register FastISel::fastEmitInst_rii(unsigned MachineInstOpcode, 21460b57cec5SDimitry Andric const TargetRegisterClass *RC, unsigned Op0, 2147fe6060f1SDimitry Andric uint64_t Imm1, uint64_t Imm2) { 21480b57cec5SDimitry Andric const MCInstrDesc &II = TII.get(MachineInstOpcode); 21490b57cec5SDimitry Andric 21505ffd83dbSDimitry Andric Register ResultReg = createResultReg(RC); 21510b57cec5SDimitry Andric Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs()); 21520b57cec5SDimitry Andric 21530b57cec5SDimitry Andric if (II.getNumDefs() >= 1) 2154bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg) 2155fe6060f1SDimitry Andric .addReg(Op0) 21560b57cec5SDimitry Andric .addImm(Imm1) 21570b57cec5SDimitry Andric .addImm(Imm2); 21580b57cec5SDimitry Andric else { 2159bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II) 2160fe6060f1SDimitry Andric .addReg(Op0) 21610b57cec5SDimitry Andric .addImm(Imm1) 21620b57cec5SDimitry Andric .addImm(Imm2); 2163bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), 2164bdd1243dSDimitry Andric ResultReg) 2165bdd1243dSDimitry Andric .addReg(II.implicit_defs()[0]); 21660b57cec5SDimitry Andric } 21670b57cec5SDimitry Andric return ResultReg; 21680b57cec5SDimitry Andric } 21690b57cec5SDimitry Andric 21705ffd83dbSDimitry Andric Register FastISel::fastEmitInst_f(unsigned MachineInstOpcode, 21710b57cec5SDimitry Andric const TargetRegisterClass *RC, 21720b57cec5SDimitry Andric const ConstantFP *FPImm) { 21730b57cec5SDimitry Andric const MCInstrDesc &II = TII.get(MachineInstOpcode); 21740b57cec5SDimitry Andric 21755ffd83dbSDimitry Andric Register ResultReg = createResultReg(RC); 21760b57cec5SDimitry Andric 21770b57cec5SDimitry Andric if (II.getNumDefs() >= 1) 2178bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg) 21790b57cec5SDimitry Andric .addFPImm(FPImm); 21800b57cec5SDimitry Andric else { 2181bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II) 21820b57cec5SDimitry Andric .addFPImm(FPImm); 2183bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), 2184bdd1243dSDimitry Andric ResultReg) 2185bdd1243dSDimitry Andric .addReg(II.implicit_defs()[0]); 21860b57cec5SDimitry Andric } 21870b57cec5SDimitry Andric return ResultReg; 21880b57cec5SDimitry Andric } 21890b57cec5SDimitry Andric 21905ffd83dbSDimitry Andric Register FastISel::fastEmitInst_rri(unsigned MachineInstOpcode, 21910b57cec5SDimitry Andric const TargetRegisterClass *RC, unsigned Op0, 2192fe6060f1SDimitry Andric unsigned Op1, uint64_t Imm) { 21930b57cec5SDimitry Andric const MCInstrDesc &II = TII.get(MachineInstOpcode); 21940b57cec5SDimitry Andric 21955ffd83dbSDimitry Andric Register ResultReg = createResultReg(RC); 21960b57cec5SDimitry Andric Op0 = constrainOperandRegClass(II, Op0, II.getNumDefs()); 21970b57cec5SDimitry Andric Op1 = constrainOperandRegClass(II, Op1, II.getNumDefs() + 1); 21980b57cec5SDimitry Andric 21990b57cec5SDimitry Andric if (II.getNumDefs() >= 1) 2200bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg) 2201fe6060f1SDimitry Andric .addReg(Op0) 2202fe6060f1SDimitry Andric .addReg(Op1) 22030b57cec5SDimitry Andric .addImm(Imm); 22040b57cec5SDimitry Andric else { 2205bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II) 2206fe6060f1SDimitry Andric .addReg(Op0) 2207fe6060f1SDimitry Andric .addReg(Op1) 22080b57cec5SDimitry Andric .addImm(Imm); 2209bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), 2210bdd1243dSDimitry Andric ResultReg) 2211bdd1243dSDimitry Andric .addReg(II.implicit_defs()[0]); 22120b57cec5SDimitry Andric } 22130b57cec5SDimitry Andric return ResultReg; 22140b57cec5SDimitry Andric } 22150b57cec5SDimitry Andric 22165ffd83dbSDimitry Andric Register FastISel::fastEmitInst_i(unsigned MachineInstOpcode, 22170b57cec5SDimitry Andric const TargetRegisterClass *RC, uint64_t Imm) { 22185ffd83dbSDimitry Andric Register ResultReg = createResultReg(RC); 22190b57cec5SDimitry Andric const MCInstrDesc &II = TII.get(MachineInstOpcode); 22200b57cec5SDimitry Andric 22210b57cec5SDimitry Andric if (II.getNumDefs() >= 1) 2222bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II, ResultReg) 22230b57cec5SDimitry Andric .addImm(Imm); 22240b57cec5SDimitry Andric else { 2225bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, II).addImm(Imm); 2226bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), 2227bdd1243dSDimitry Andric ResultReg) 2228bdd1243dSDimitry Andric .addReg(II.implicit_defs()[0]); 22290b57cec5SDimitry Andric } 22300b57cec5SDimitry Andric return ResultReg; 22310b57cec5SDimitry Andric } 22320b57cec5SDimitry Andric 22335ffd83dbSDimitry Andric Register FastISel::fastEmitInst_extractsubreg(MVT RetVT, unsigned Op0, 2234fe6060f1SDimitry Andric uint32_t Idx) { 22355ffd83dbSDimitry Andric Register ResultReg = createResultReg(TLI.getRegClassFor(RetVT)); 22368bcb0991SDimitry Andric assert(Register::isVirtualRegister(Op0) && 22370b57cec5SDimitry Andric "Cannot yet extract from physregs"); 22380b57cec5SDimitry Andric const TargetRegisterClass *RC = MRI.getRegClass(Op0); 22390b57cec5SDimitry Andric MRI.constrainRegClass(Op0, TRI.getSubClassWithSubReg(RC, Idx)); 2240bdd1243dSDimitry Andric BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, MIMD, TII.get(TargetOpcode::COPY), 2241fe6060f1SDimitry Andric ResultReg).addReg(Op0, 0, Idx); 22420b57cec5SDimitry Andric return ResultReg; 22430b57cec5SDimitry Andric } 22440b57cec5SDimitry Andric 22450b57cec5SDimitry Andric /// Emit MachineInstrs to compute the value of Op with all but the least 22460b57cec5SDimitry Andric /// significant bit set to zero. 2247fe6060f1SDimitry Andric Register FastISel::fastEmitZExtFromI1(MVT VT, unsigned Op0) { 2248fe6060f1SDimitry Andric return fastEmit_ri(VT, VT, ISD::AND, Op0, 1); 22490b57cec5SDimitry Andric } 22500b57cec5SDimitry Andric 22510b57cec5SDimitry Andric /// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks. 22520b57cec5SDimitry Andric /// Emit code to ensure constants are copied into registers when needed. 22530b57cec5SDimitry Andric /// Remember the virtual registers that need to be added to the Machine PHI 22540b57cec5SDimitry Andric /// nodes as input. We cannot just directly add them, because expansion 22550b57cec5SDimitry Andric /// might result in multiple MBB's for one BB. As such, the start of the 22560b57cec5SDimitry Andric /// BB might correspond to a different MBB than the end. 22570b57cec5SDimitry Andric bool FastISel::handlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB) { 22580b57cec5SDimitry Andric SmallPtrSet<MachineBasicBlock *, 4> SuccsHandled; 22590b57cec5SDimitry Andric FuncInfo.OrigNumPHINodesToUpdate = FuncInfo.PHINodesToUpdate.size(); 22600b57cec5SDimitry Andric 22610b57cec5SDimitry Andric // Check successor nodes' PHI nodes that expect a constant to be available 22620b57cec5SDimitry Andric // from this block. 22637a6dacacSDimitry Andric for (const BasicBlock *SuccBB : successors(LLVMBB)) { 22640b57cec5SDimitry Andric if (!isa<PHINode>(SuccBB->begin())) 22650b57cec5SDimitry Andric continue; 22660b57cec5SDimitry Andric MachineBasicBlock *SuccMBB = FuncInfo.MBBMap[SuccBB]; 22670b57cec5SDimitry Andric 22680b57cec5SDimitry Andric // If this terminator has multiple identical successors (common for 22690b57cec5SDimitry Andric // switches), only handle each succ once. 22700b57cec5SDimitry Andric if (!SuccsHandled.insert(SuccMBB).second) 22710b57cec5SDimitry Andric continue; 22720b57cec5SDimitry Andric 22730b57cec5SDimitry Andric MachineBasicBlock::iterator MBBI = SuccMBB->begin(); 22740b57cec5SDimitry Andric 22750b57cec5SDimitry Andric // At this point we know that there is a 1-1 correspondence between LLVM PHI 22760b57cec5SDimitry Andric // nodes and Machine PHI nodes, but the incoming operands have not been 22770b57cec5SDimitry Andric // emitted yet. 22780b57cec5SDimitry Andric for (const PHINode &PN : SuccBB->phis()) { 22790b57cec5SDimitry Andric // Ignore dead phi's. 22800b57cec5SDimitry Andric if (PN.use_empty()) 22810b57cec5SDimitry Andric continue; 22820b57cec5SDimitry Andric 22830b57cec5SDimitry Andric // Only handle legal types. Two interesting things to note here. First, 22840b57cec5SDimitry Andric // by bailing out early, we may leave behind some dead instructions, 22850b57cec5SDimitry Andric // since SelectionDAG's HandlePHINodesInSuccessorBlocks will insert its 22860b57cec5SDimitry Andric // own moves. Second, this check is necessary because FastISel doesn't 22870b57cec5SDimitry Andric // use CreateRegs to create registers, so it always creates 22880b57cec5SDimitry Andric // exactly one register for each non-void instruction. 22890b57cec5SDimitry Andric EVT VT = TLI.getValueType(DL, PN.getType(), /*AllowUnknown=*/true); 22900b57cec5SDimitry Andric if (VT == MVT::Other || !TLI.isTypeLegal(VT)) { 22910b57cec5SDimitry Andric // Handle integer promotions, though, because they're common and easy. 22920b57cec5SDimitry Andric if (!(VT == MVT::i1 || VT == MVT::i8 || VT == MVT::i16)) { 22930b57cec5SDimitry Andric FuncInfo.PHINodesToUpdate.resize(FuncInfo.OrigNumPHINodesToUpdate); 22940b57cec5SDimitry Andric return false; 22950b57cec5SDimitry Andric } 22960b57cec5SDimitry Andric } 22970b57cec5SDimitry Andric 22980b57cec5SDimitry Andric const Value *PHIOp = PN.getIncomingValueForBlock(LLVMBB); 22990b57cec5SDimitry Andric 2300e8d8bef9SDimitry Andric // Set the DebugLoc for the copy. Use the location of the operand if 2301e8d8bef9SDimitry Andric // there is one; otherwise no location, flushLocalValueMap will fix it. 2302bdd1243dSDimitry Andric MIMD = {}; 23030b57cec5SDimitry Andric if (const auto *Inst = dyn_cast<Instruction>(PHIOp)) 2304bdd1243dSDimitry Andric MIMD = MIMetadata(*Inst); 23050b57cec5SDimitry Andric 23065ffd83dbSDimitry Andric Register Reg = getRegForValue(PHIOp); 23070b57cec5SDimitry Andric if (!Reg) { 23080b57cec5SDimitry Andric FuncInfo.PHINodesToUpdate.resize(FuncInfo.OrigNumPHINodesToUpdate); 23090b57cec5SDimitry Andric return false; 23100b57cec5SDimitry Andric } 23110b57cec5SDimitry Andric FuncInfo.PHINodesToUpdate.push_back(std::make_pair(&*MBBI++, Reg)); 2312bdd1243dSDimitry Andric MIMD = {}; 23130b57cec5SDimitry Andric } 23140b57cec5SDimitry Andric } 23150b57cec5SDimitry Andric 23160b57cec5SDimitry Andric return true; 23170b57cec5SDimitry Andric } 23180b57cec5SDimitry Andric 23190b57cec5SDimitry Andric bool FastISel::tryToFoldLoad(const LoadInst *LI, const Instruction *FoldInst) { 23200b57cec5SDimitry Andric assert(LI->hasOneUse() && 23210b57cec5SDimitry Andric "tryToFoldLoad expected a LoadInst with a single use"); 23220b57cec5SDimitry Andric // We know that the load has a single use, but don't know what it is. If it 23230b57cec5SDimitry Andric // isn't one of the folded instructions, then we can't succeed here. Handle 23240b57cec5SDimitry Andric // this by scanning the single-use users of the load until we get to FoldInst. 23250b57cec5SDimitry Andric unsigned MaxUsers = 6; // Don't scan down huge single-use chains of instrs. 23260b57cec5SDimitry Andric 23270b57cec5SDimitry Andric const Instruction *TheUser = LI->user_back(); 23280b57cec5SDimitry Andric while (TheUser != FoldInst && // Scan up until we find FoldInst. 23290b57cec5SDimitry Andric // Stay in the right block. 23300b57cec5SDimitry Andric TheUser->getParent() == FoldInst->getParent() && 23310b57cec5SDimitry Andric --MaxUsers) { // Don't scan too far. 23320b57cec5SDimitry Andric // If there are multiple or no uses of this instruction, then bail out. 23330b57cec5SDimitry Andric if (!TheUser->hasOneUse()) 23340b57cec5SDimitry Andric return false; 23350b57cec5SDimitry Andric 23360b57cec5SDimitry Andric TheUser = TheUser->user_back(); 23370b57cec5SDimitry Andric } 23380b57cec5SDimitry Andric 23390b57cec5SDimitry Andric // If we didn't find the fold instruction, then we failed to collapse the 23400b57cec5SDimitry Andric // sequence. 23410b57cec5SDimitry Andric if (TheUser != FoldInst) 23420b57cec5SDimitry Andric return false; 23430b57cec5SDimitry Andric 23440b57cec5SDimitry Andric // Don't try to fold volatile loads. Target has to deal with alignment 23450b57cec5SDimitry Andric // constraints. 23460b57cec5SDimitry Andric if (LI->isVolatile()) 23470b57cec5SDimitry Andric return false; 23480b57cec5SDimitry Andric 23490b57cec5SDimitry Andric // Figure out which vreg this is going into. If there is no assigned vreg yet 23500b57cec5SDimitry Andric // then there actually was no reference to it. Perhaps the load is referenced 23510b57cec5SDimitry Andric // by a dead instruction. 23525ffd83dbSDimitry Andric Register LoadReg = getRegForValue(LI); 23530b57cec5SDimitry Andric if (!LoadReg) 23540b57cec5SDimitry Andric return false; 23550b57cec5SDimitry Andric 23560b57cec5SDimitry Andric // We can't fold if this vreg has no uses or more than one use. Multiple uses 23570b57cec5SDimitry Andric // may mean that the instruction got lowered to multiple MIs, or the use of 23580b57cec5SDimitry Andric // the loaded value ended up being multiple operands of the result. 23590b57cec5SDimitry Andric if (!MRI.hasOneUse(LoadReg)) 23600b57cec5SDimitry Andric return false; 23610b57cec5SDimitry Andric 236281ad6265SDimitry Andric // If the register has fixups, there may be additional uses through a 236381ad6265SDimitry Andric // different alias of the register. 236481ad6265SDimitry Andric if (FuncInfo.RegsWithFixups.contains(LoadReg)) 236581ad6265SDimitry Andric return false; 236681ad6265SDimitry Andric 23670b57cec5SDimitry Andric MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(LoadReg); 23680b57cec5SDimitry Andric MachineInstr *User = RI->getParent(); 23690b57cec5SDimitry Andric 23700b57cec5SDimitry Andric // Set the insertion point properly. Folding the load can cause generation of 23710b57cec5SDimitry Andric // other random instructions (like sign extends) for addressing modes; make 23720b57cec5SDimitry Andric // sure they get inserted in a logical place before the new instruction. 23730b57cec5SDimitry Andric FuncInfo.InsertPt = User; 23740b57cec5SDimitry Andric FuncInfo.MBB = User->getParent(); 23750b57cec5SDimitry Andric 23760b57cec5SDimitry Andric // Ask the target to try folding the load. 23770b57cec5SDimitry Andric return tryToFoldLoadIntoMI(User, RI.getOperandNo(), LI); 23780b57cec5SDimitry Andric } 23790b57cec5SDimitry Andric 23800b57cec5SDimitry Andric bool FastISel::canFoldAddIntoGEP(const User *GEP, const Value *Add) { 23810b57cec5SDimitry Andric // Must be an add. 23820b57cec5SDimitry Andric if (!isa<AddOperator>(Add)) 23830b57cec5SDimitry Andric return false; 23840b57cec5SDimitry Andric // Type size needs to match. 23850b57cec5SDimitry Andric if (DL.getTypeSizeInBits(GEP->getType()) != 23860b57cec5SDimitry Andric DL.getTypeSizeInBits(Add->getType())) 23870b57cec5SDimitry Andric return false; 23880b57cec5SDimitry Andric // Must be in the same basic block. 23890b57cec5SDimitry Andric if (isa<Instruction>(Add) && 23900b57cec5SDimitry Andric FuncInfo.MBBMap[cast<Instruction>(Add)->getParent()] != FuncInfo.MBB) 23910b57cec5SDimitry Andric return false; 23920b57cec5SDimitry Andric // Must have a constant operand. 23930b57cec5SDimitry Andric return isa<ConstantInt>(cast<AddOperator>(Add)->getOperand(1)); 23940b57cec5SDimitry Andric } 23950b57cec5SDimitry Andric 23960b57cec5SDimitry Andric MachineMemOperand * 23970b57cec5SDimitry Andric FastISel::createMachineMemOperandFor(const Instruction *I) const { 23980b57cec5SDimitry Andric const Value *Ptr; 23990b57cec5SDimitry Andric Type *ValTy; 24005ffd83dbSDimitry Andric MaybeAlign Alignment; 24010b57cec5SDimitry Andric MachineMemOperand::Flags Flags; 24020b57cec5SDimitry Andric bool IsVolatile; 24030b57cec5SDimitry Andric 24040b57cec5SDimitry Andric if (const auto *LI = dyn_cast<LoadInst>(I)) { 24055ffd83dbSDimitry Andric Alignment = LI->getAlign(); 24060b57cec5SDimitry Andric IsVolatile = LI->isVolatile(); 24070b57cec5SDimitry Andric Flags = MachineMemOperand::MOLoad; 24080b57cec5SDimitry Andric Ptr = LI->getPointerOperand(); 24090b57cec5SDimitry Andric ValTy = LI->getType(); 24100b57cec5SDimitry Andric } else if (const auto *SI = dyn_cast<StoreInst>(I)) { 24115ffd83dbSDimitry Andric Alignment = SI->getAlign(); 24120b57cec5SDimitry Andric IsVolatile = SI->isVolatile(); 24130b57cec5SDimitry Andric Flags = MachineMemOperand::MOStore; 24140b57cec5SDimitry Andric Ptr = SI->getPointerOperand(); 24150b57cec5SDimitry Andric ValTy = SI->getValueOperand()->getType(); 24160b57cec5SDimitry Andric } else 24170b57cec5SDimitry Andric return nullptr; 24180b57cec5SDimitry Andric 24198bcb0991SDimitry Andric bool IsNonTemporal = I->hasMetadata(LLVMContext::MD_nontemporal); 24208bcb0991SDimitry Andric bool IsInvariant = I->hasMetadata(LLVMContext::MD_invariant_load); 24218bcb0991SDimitry Andric bool IsDereferenceable = I->hasMetadata(LLVMContext::MD_dereferenceable); 24220b57cec5SDimitry Andric const MDNode *Ranges = I->getMetadata(LLVMContext::MD_range); 24230b57cec5SDimitry Andric 2424349cc55cSDimitry Andric AAMDNodes AAInfo = I->getAAMetadata(); 24250b57cec5SDimitry Andric 24265ffd83dbSDimitry Andric if (!Alignment) // Ensure that codegen never sees alignment 0. 24275ffd83dbSDimitry Andric Alignment = DL.getABITypeAlign(ValTy); 24280b57cec5SDimitry Andric 24290b57cec5SDimitry Andric unsigned Size = DL.getTypeStoreSize(ValTy); 24300b57cec5SDimitry Andric 24310b57cec5SDimitry Andric if (IsVolatile) 24320b57cec5SDimitry Andric Flags |= MachineMemOperand::MOVolatile; 24330b57cec5SDimitry Andric if (IsNonTemporal) 24340b57cec5SDimitry Andric Flags |= MachineMemOperand::MONonTemporal; 24350b57cec5SDimitry Andric if (IsDereferenceable) 24360b57cec5SDimitry Andric Flags |= MachineMemOperand::MODereferenceable; 24370b57cec5SDimitry Andric if (IsInvariant) 24380b57cec5SDimitry Andric Flags |= MachineMemOperand::MOInvariant; 24390b57cec5SDimitry Andric 24400b57cec5SDimitry Andric return FuncInfo.MF->getMachineMemOperand(MachinePointerInfo(Ptr), Flags, Size, 24415ffd83dbSDimitry Andric *Alignment, AAInfo, Ranges); 24420b57cec5SDimitry Andric } 24430b57cec5SDimitry Andric 24440b57cec5SDimitry Andric CmpInst::Predicate FastISel::optimizeCmpPredicate(const CmpInst *CI) const { 24450b57cec5SDimitry Andric // If both operands are the same, then try to optimize or fold the cmp. 24460b57cec5SDimitry Andric CmpInst::Predicate Predicate = CI->getPredicate(); 24470b57cec5SDimitry Andric if (CI->getOperand(0) != CI->getOperand(1)) 24480b57cec5SDimitry Andric return Predicate; 24490b57cec5SDimitry Andric 24500b57cec5SDimitry Andric switch (Predicate) { 24510b57cec5SDimitry Andric default: llvm_unreachable("Invalid predicate!"); 24520b57cec5SDimitry Andric case CmpInst::FCMP_FALSE: Predicate = CmpInst::FCMP_FALSE; break; 24530b57cec5SDimitry Andric case CmpInst::FCMP_OEQ: Predicate = CmpInst::FCMP_ORD; break; 24540b57cec5SDimitry Andric case CmpInst::FCMP_OGT: Predicate = CmpInst::FCMP_FALSE; break; 24550b57cec5SDimitry Andric case CmpInst::FCMP_OGE: Predicate = CmpInst::FCMP_ORD; break; 24560b57cec5SDimitry Andric case CmpInst::FCMP_OLT: Predicate = CmpInst::FCMP_FALSE; break; 24570b57cec5SDimitry Andric case CmpInst::FCMP_OLE: Predicate = CmpInst::FCMP_ORD; break; 24580b57cec5SDimitry Andric case CmpInst::FCMP_ONE: Predicate = CmpInst::FCMP_FALSE; break; 24590b57cec5SDimitry Andric case CmpInst::FCMP_ORD: Predicate = CmpInst::FCMP_ORD; break; 24600b57cec5SDimitry Andric case CmpInst::FCMP_UNO: Predicate = CmpInst::FCMP_UNO; break; 24610b57cec5SDimitry Andric case CmpInst::FCMP_UEQ: Predicate = CmpInst::FCMP_TRUE; break; 24620b57cec5SDimitry Andric case CmpInst::FCMP_UGT: Predicate = CmpInst::FCMP_UNO; break; 24630b57cec5SDimitry Andric case CmpInst::FCMP_UGE: Predicate = CmpInst::FCMP_TRUE; break; 24640b57cec5SDimitry Andric case CmpInst::FCMP_ULT: Predicate = CmpInst::FCMP_UNO; break; 24650b57cec5SDimitry Andric case CmpInst::FCMP_ULE: Predicate = CmpInst::FCMP_TRUE; break; 24660b57cec5SDimitry Andric case CmpInst::FCMP_UNE: Predicate = CmpInst::FCMP_UNO; break; 24670b57cec5SDimitry Andric case CmpInst::FCMP_TRUE: Predicate = CmpInst::FCMP_TRUE; break; 24680b57cec5SDimitry Andric 24690b57cec5SDimitry Andric case CmpInst::ICMP_EQ: Predicate = CmpInst::FCMP_TRUE; break; 24700b57cec5SDimitry Andric case CmpInst::ICMP_NE: Predicate = CmpInst::FCMP_FALSE; break; 24710b57cec5SDimitry Andric case CmpInst::ICMP_UGT: Predicate = CmpInst::FCMP_FALSE; break; 24720b57cec5SDimitry Andric case CmpInst::ICMP_UGE: Predicate = CmpInst::FCMP_TRUE; break; 24730b57cec5SDimitry Andric case CmpInst::ICMP_ULT: Predicate = CmpInst::FCMP_FALSE; break; 24740b57cec5SDimitry Andric case CmpInst::ICMP_ULE: Predicate = CmpInst::FCMP_TRUE; break; 24750b57cec5SDimitry Andric case CmpInst::ICMP_SGT: Predicate = CmpInst::FCMP_FALSE; break; 24760b57cec5SDimitry Andric case CmpInst::ICMP_SGE: Predicate = CmpInst::FCMP_TRUE; break; 24770b57cec5SDimitry Andric case CmpInst::ICMP_SLT: Predicate = CmpInst::FCMP_FALSE; break; 24780b57cec5SDimitry Andric case CmpInst::ICMP_SLE: Predicate = CmpInst::FCMP_TRUE; break; 24790b57cec5SDimitry Andric } 24800b57cec5SDimitry Andric 24810b57cec5SDimitry Andric return Predicate; 24820b57cec5SDimitry Andric } 2483