File indexing completed on 2026-05-10 08:43:28
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CODEGEN_FASTISEL_H
0015 #define LLVM_CODEGEN_FASTISEL_H
0016
0017 #include "llvm/ADT/DenseMap.h"
0018 #include "llvm/ADT/SmallVector.h"
0019 #include "llvm/ADT/StringRef.h"
0020 #include "llvm/CodeGen/MachineBasicBlock.h"
0021 #include "llvm/CodeGen/MachineInstrBuilder.h"
0022 #include "llvm/CodeGen/TargetLowering.h"
0023 #include "llvm/CodeGenTypes/MachineValueType.h"
0024 #include "llvm/IR/Attributes.h"
0025 #include "llvm/IR/CallingConv.h"
0026 #include "llvm/IR/DebugLoc.h"
0027 #include "llvm/IR/DerivedTypes.h"
0028 #include "llvm/IR/InstrTypes.h"
0029 #include <cstdint>
0030 #include <utility>
0031
0032 namespace llvm {
0033
0034 class AllocaInst;
0035 class Instruction;
0036 class IntrinsicInst;
0037 class BasicBlock;
0038 class CallInst;
0039 class Constant;
0040 class ConstantFP;
0041 class DataLayout;
0042 class FunctionLoweringInfo;
0043 class LoadInst;
0044 class MachineConstantPool;
0045 class MachineFrameInfo;
0046 class MachineFunction;
0047 class MachineInstr;
0048 class MachineMemOperand;
0049 class MachineOperand;
0050 class MachineRegisterInfo;
0051 class MCContext;
0052 class MCInstrDesc;
0053 class MCSymbol;
0054 class TargetInstrInfo;
0055 class TargetLibraryInfo;
0056 class TargetMachine;
0057 class TargetRegisterClass;
0058 class TargetRegisterInfo;
0059 class Type;
0060 class User;
0061 class Value;
0062
0063
0064
0065
0066 class FastISel {
0067 public:
0068 using ArgListEntry = TargetLoweringBase::ArgListEntry;
0069 using ArgListTy = TargetLoweringBase::ArgListTy;
0070 struct CallLoweringInfo {
0071 Type *RetTy = nullptr;
0072 bool RetSExt : 1;
0073 bool RetZExt : 1;
0074 bool IsVarArg : 1;
0075 bool IsInReg : 1;
0076 bool DoesNotReturn : 1;
0077 bool IsReturnValueUsed : 1;
0078 bool IsPatchPoint : 1;
0079
0080
0081
0082 bool IsTailCall = false;
0083
0084 unsigned NumFixedArgs = -1;
0085 CallingConv::ID CallConv = CallingConv::C;
0086 const Value *Callee = nullptr;
0087 MCSymbol *Symbol = nullptr;
0088 ArgListTy Args;
0089 const CallBase *CB = nullptr;
0090 MachineInstr *Call = nullptr;
0091 Register ResultReg;
0092 unsigned NumResultRegs = 0;
0093
0094 SmallVector<Value *, 16> OutVals;
0095 SmallVector<ISD::ArgFlagsTy, 16> OutFlags;
0096 SmallVector<Register, 16> OutRegs;
0097 SmallVector<ISD::InputArg, 4> Ins;
0098 SmallVector<Register, 4> InRegs;
0099
0100 CallLoweringInfo()
0101 : RetSExt(false), RetZExt(false), IsVarArg(false), IsInReg(false),
0102 DoesNotReturn(false), IsReturnValueUsed(true), IsPatchPoint(false) {}
0103
0104 CallLoweringInfo &setCallee(Type *ResultTy, FunctionType *FuncTy,
0105 const Value *Target, ArgListTy &&ArgsList,
0106 const CallBase &Call) {
0107 RetTy = ResultTy;
0108 Callee = Target;
0109
0110 IsInReg = Call.hasRetAttr(Attribute::InReg);
0111 DoesNotReturn = Call.doesNotReturn();
0112 IsVarArg = FuncTy->isVarArg();
0113 IsReturnValueUsed = !Call.use_empty();
0114 RetSExt = Call.hasRetAttr(Attribute::SExt);
0115 RetZExt = Call.hasRetAttr(Attribute::ZExt);
0116
0117 CallConv = Call.getCallingConv();
0118 Args = std::move(ArgsList);
0119 NumFixedArgs = FuncTy->getNumParams();
0120
0121 CB = &Call;
0122
0123 return *this;
0124 }
0125
0126 CallLoweringInfo &setCallee(Type *ResultTy, FunctionType *FuncTy,
0127 MCSymbol *Target, ArgListTy &&ArgsList,
0128 const CallBase &Call,
0129 unsigned FixedArgs = ~0U) {
0130 RetTy = ResultTy;
0131 Callee = Call.getCalledOperand();
0132 Symbol = Target;
0133
0134 IsInReg = Call.hasRetAttr(Attribute::InReg);
0135 DoesNotReturn = Call.doesNotReturn();
0136 IsVarArg = FuncTy->isVarArg();
0137 IsReturnValueUsed = !Call.use_empty();
0138 RetSExt = Call.hasRetAttr(Attribute::SExt);
0139 RetZExt = Call.hasRetAttr(Attribute::ZExt);
0140
0141 CallConv = Call.getCallingConv();
0142 Args = std::move(ArgsList);
0143 NumFixedArgs = (FixedArgs == ~0U) ? FuncTy->getNumParams() : FixedArgs;
0144
0145 CB = &Call;
0146
0147 return *this;
0148 }
0149
0150 CallLoweringInfo &setCallee(CallingConv::ID CC, Type *ResultTy,
0151 const Value *Target, ArgListTy &&ArgsList,
0152 unsigned FixedArgs = ~0U) {
0153 RetTy = ResultTy;
0154 Callee = Target;
0155 CallConv = CC;
0156 Args = std::move(ArgsList);
0157 NumFixedArgs = (FixedArgs == ~0U) ? Args.size() : FixedArgs;
0158 return *this;
0159 }
0160
0161 CallLoweringInfo &setCallee(const DataLayout &DL, MCContext &Ctx,
0162 CallingConv::ID CC, Type *ResultTy,
0163 StringRef Target, ArgListTy &&ArgsList,
0164 unsigned FixedArgs = ~0U);
0165
0166 CallLoweringInfo &setCallee(CallingConv::ID CC, Type *ResultTy,
0167 MCSymbol *Target, ArgListTy &&ArgsList,
0168 unsigned FixedArgs = ~0U) {
0169 RetTy = ResultTy;
0170 Symbol = Target;
0171 CallConv = CC;
0172 Args = std::move(ArgsList);
0173 NumFixedArgs = (FixedArgs == ~0U) ? Args.size() : FixedArgs;
0174 return *this;
0175 }
0176
0177 CallLoweringInfo &setTailCall(bool Value = true) {
0178 IsTailCall = Value;
0179 return *this;
0180 }
0181
0182 CallLoweringInfo &setIsPatchPoint(bool Value = true) {
0183 IsPatchPoint = Value;
0184 return *this;
0185 }
0186
0187 ArgListTy &getArgs() { return Args; }
0188
0189 void clearOuts() {
0190 OutVals.clear();
0191 OutFlags.clear();
0192 OutRegs.clear();
0193 }
0194
0195 void clearIns() {
0196 Ins.clear();
0197 InRegs.clear();
0198 }
0199 };
0200
0201 protected:
0202 DenseMap<const Value *, Register> LocalValueMap;
0203 FunctionLoweringInfo &FuncInfo;
0204 MachineFunction *MF;
0205 MachineRegisterInfo &MRI;
0206 MachineFrameInfo &MFI;
0207 MachineConstantPool &MCP;
0208 MIMetadata MIMD;
0209 const TargetMachine &TM;
0210 const DataLayout &DL;
0211 const TargetInstrInfo &TII;
0212 const TargetLowering &TLI;
0213 const TargetRegisterInfo &TRI;
0214 const TargetLibraryInfo *LibInfo;
0215 bool SkipTargetIndependentISel;
0216
0217
0218
0219
0220
0221 MachineInstr *LastLocalValue = nullptr;
0222
0223
0224
0225
0226 MachineInstr *EmitStartPt = nullptr;
0227
0228 public:
0229 virtual ~FastISel();
0230
0231
0232
0233 MachineInstr *getLastLocalValue() { return LastLocalValue; }
0234
0235
0236
0237 void setLastLocalValue(MachineInstr *I) {
0238 EmitStartPt = I;
0239 LastLocalValue = I;
0240 }
0241
0242
0243
0244 void startNewBlock();
0245
0246
0247 void finishBasicBlock();
0248
0249
0250 DebugLoc getCurDebugLoc() const { return MIMD.getDL(); }
0251
0252
0253
0254
0255 bool lowerArguments();
0256
0257
0258
0259
0260 bool selectInstruction(const Instruction *I);
0261
0262
0263
0264
0265 bool selectOperator(const User *I, unsigned Opcode);
0266
0267
0268
0269 Register getRegForValue(const Value *V);
0270
0271
0272
0273
0274 Register lookUpRegForValue(const Value *V);
0275
0276
0277
0278 Register getRegForGEPIndex(MVT PtrVT, const Value *Idx);
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292 bool tryToFoldLoad(const LoadInst *LI, const Instruction *FoldInst);
0293
0294
0295
0296
0297
0298
0299
0300 virtual bool tryToFoldLoadIntoMI(MachineInstr * , unsigned ,
0301 const LoadInst * ) {
0302 return false;
0303 }
0304
0305
0306
0307 void recomputeInsertPt();
0308
0309
0310 void removeDeadCode(MachineBasicBlock::iterator I,
0311 MachineBasicBlock::iterator E);
0312
0313 using SavePoint = MachineBasicBlock::iterator;
0314
0315
0316
0317 SavePoint enterLocalValueArea();
0318
0319
0320 void leaveLocalValueArea(SavePoint Old);
0321
0322
0323
0324 void handleDbgInfo(const Instruction *II);
0325
0326 protected:
0327 explicit FastISel(FunctionLoweringInfo &FuncInfo,
0328 const TargetLibraryInfo *LibInfo,
0329 bool SkipTargetIndependentISel = false);
0330
0331
0332
0333
0334
0335 virtual bool fastSelectInstruction(const Instruction *I) = 0;
0336
0337
0338
0339 virtual bool fastLowerArguments();
0340
0341
0342
0343 virtual bool fastLowerCall(CallLoweringInfo &CLI);
0344
0345
0346
0347 virtual bool fastLowerIntrinsicCall(const IntrinsicInst *II);
0348
0349
0350
0351 virtual unsigned fastEmit_(MVT VT, MVT RetVT, unsigned Opcode);
0352
0353
0354
0355 virtual unsigned fastEmit_r(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0);
0356
0357
0358
0359 virtual unsigned fastEmit_rr(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0,
0360 unsigned Op1);
0361
0362
0363
0364
0365 virtual unsigned fastEmit_ri(MVT VT, MVT RetVT, unsigned Opcode, unsigned Op0,
0366 uint64_t Imm);
0367
0368
0369
0370
0371
0372
0373 Register fastEmit_ri_(MVT VT, unsigned Opcode, unsigned Op0, uint64_t Imm,
0374 MVT ImmType);
0375
0376
0377
0378 virtual unsigned fastEmit_i(MVT VT, MVT RetVT, unsigned Opcode, uint64_t Imm);
0379
0380
0381
0382
0383 virtual unsigned fastEmit_f(MVT VT, MVT RetVT, unsigned Opcode,
0384 const ConstantFP *FPImm);
0385
0386
0387
0388 Register fastEmitInst_(unsigned MachineInstOpcode,
0389 const TargetRegisterClass *RC);
0390
0391
0392
0393 Register fastEmitInst_r(unsigned MachineInstOpcode,
0394 const TargetRegisterClass *RC, unsigned Op0);
0395
0396
0397
0398 Register fastEmitInst_rr(unsigned MachineInstOpcode,
0399 const TargetRegisterClass *RC, unsigned Op0,
0400 unsigned Op1);
0401
0402
0403
0404 Register fastEmitInst_rrr(unsigned MachineInstOpcode,
0405 const TargetRegisterClass *RC, unsigned Op0,
0406 unsigned Op1, unsigned Op2);
0407
0408
0409
0410 Register fastEmitInst_ri(unsigned MachineInstOpcode,
0411 const TargetRegisterClass *RC, unsigned Op0,
0412 uint64_t Imm);
0413
0414
0415
0416 Register fastEmitInst_rii(unsigned MachineInstOpcode,
0417 const TargetRegisterClass *RC, unsigned Op0,
0418 uint64_t Imm1, uint64_t Imm2);
0419
0420
0421
0422 Register fastEmitInst_f(unsigned MachineInstOpcode,
0423 const TargetRegisterClass *RC,
0424 const ConstantFP *FPImm);
0425
0426
0427
0428 Register fastEmitInst_rri(unsigned MachineInstOpcode,
0429 const TargetRegisterClass *RC, unsigned Op0,
0430 unsigned Op1, uint64_t Imm);
0431
0432
0433
0434 Register fastEmitInst_i(unsigned MachineInstOpcode,
0435 const TargetRegisterClass *RC, uint64_t Imm);
0436
0437
0438
0439 Register fastEmitInst_extractsubreg(MVT RetVT, unsigned Op0, uint32_t Idx);
0440
0441
0442
0443 Register fastEmitZExtFromI1(MVT VT, unsigned Op0);
0444
0445
0446
0447 void fastEmitBranch(MachineBasicBlock *MSucc, const DebugLoc &DbgLoc);
0448
0449
0450
0451 void finishCondBranch(const BasicBlock *BranchBB, MachineBasicBlock *TrueMBB,
0452 MachineBasicBlock *FalseMBB);
0453
0454
0455
0456
0457
0458
0459
0460
0461 void updateValueMap(const Value *I, Register Reg, unsigned NumRegs = 1);
0462
0463 Register createResultReg(const TargetRegisterClass *RC);
0464
0465
0466
0467
0468 Register constrainOperandRegClass(const MCInstrDesc &II, Register Op,
0469 unsigned OpNum);
0470
0471
0472
0473 virtual unsigned fastMaterializeConstant(const Constant *C) { return 0; }
0474
0475
0476 virtual unsigned fastMaterializeAlloca(const AllocaInst *C) { return 0; }
0477
0478
0479
0480 virtual unsigned fastMaterializeFloatZero(const ConstantFP *CF) {
0481 return 0;
0482 }
0483
0484
0485
0486
0487
0488
0489
0490
0491 bool canFoldAddIntoGEP(const User *GEP, const Value *Add);
0492
0493
0494 MachineMemOperand *createMachineMemOperandFor(const Instruction *I) const;
0495
0496 CmpInst::Predicate optimizeCmpPredicate(const CmpInst *CI) const;
0497
0498 bool lowerCallTo(const CallInst *CI, MCSymbol *Symbol, unsigned NumArgs);
0499 bool lowerCallTo(const CallInst *CI, const char *SymName,
0500 unsigned NumArgs);
0501 bool lowerCallTo(CallLoweringInfo &CLI);
0502
0503 bool lowerCall(const CallInst *I);
0504
0505
0506 bool selectBinaryOp(const User *I, unsigned ISDOpcode);
0507 bool selectFNeg(const User *I, const Value *In);
0508 bool selectGetElementPtr(const User *I);
0509 bool selectStackmap(const CallInst *I);
0510 bool selectPatchpoint(const CallInst *I);
0511 bool selectCall(const User *I);
0512 bool selectIntrinsicCall(const IntrinsicInst *II);
0513 bool selectBitCast(const User *I);
0514 bool selectFreeze(const User *I);
0515 bool selectCast(const User *I, unsigned Opcode);
0516 bool selectExtractValue(const User *U);
0517 bool selectXRayCustomEvent(const CallInst *II);
0518 bool selectXRayTypedEvent(const CallInst *II);
0519
0520 bool shouldOptForSize(const MachineFunction *MF) const {
0521
0522 return MF->getFunction().hasOptSize();
0523 }
0524
0525
0526
0527 virtual bool lowerDbgValue(const Value *V, DIExpression *Expr,
0528 DILocalVariable *Var, const DebugLoc &DL);
0529
0530
0531
0532 virtual bool lowerDbgDeclare(const Value *V, DIExpression *Expr,
0533 DILocalVariable *Var, const DebugLoc &DL);
0534
0535 private:
0536
0537
0538
0539
0540
0541
0542
0543 bool handlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
0544
0545
0546
0547 Register materializeConstant(const Value *V, MVT VT);
0548
0549
0550
0551
0552 Register materializeRegForValue(const Value *V, MVT VT);
0553
0554
0555
0556
0557 void flushLocalValueMap();
0558
0559
0560 void removeDeadLocalValueCode(MachineInstr *SavedLastLocalValue);
0561
0562
0563 MachineBasicBlock::iterator SavedInsertPt;
0564
0565
0566
0567 bool addStackMapLiveVars(SmallVectorImpl<MachineOperand> &Ops,
0568 const CallInst *CI, unsigned StartIdx);
0569 bool lowerCallOperands(const CallInst *CI, unsigned ArgIdx, unsigned NumArgs,
0570 const Value *Callee, bool ForceRetVoidTy,
0571 CallLoweringInfo &CLI);
0572 };
0573
0574 }
0575
0576 #endif