75 #define DEBUG_TYPE "irtranslator" 81 cl::desc(
"Should enable CSE in irtranslator"),
100 if (!R.getLocation().isValid() || TPC.isGlobalISelAbortEnabled())
101 R << (
" (in function: " + MF.getName() +
")").str();
103 if (TPC.isGlobalISelAbortEnabled())
121 DILocationVerifier() =
default;
122 ~DILocationVerifier() =
default;
124 const Instruction *getCurrentInst()
const {
return CurrInst; }
125 void setCurrentInst(
const Instruction *Inst) { CurrInst = Inst; }
132 assert(getCurrentInst() &&
"Inserted instruction without a current MI");
137 <<
" was copied to " << MI);
140 "Line info was not transferred to all instructions");
144 #endif // ifndef NDEBUG 158 uint64_t StartingOffset = 0) {
160 if (
StructType *STy = dyn_cast<StructType>(&Ty)) {
162 for (
unsigned I = 0,
E = STy->getNumElements();
I !=
E; ++
I)
168 if (
ArrayType *ATy = dyn_cast<ArrayType>(&Ty)) {
169 Type *EltTy = ATy->getElementType();
171 for (
unsigned i = 0, e = ATy->getNumElements(); i != e; ++i)
173 StartingOffset + i * EltSize);
182 Offsets->push_back(StartingOffset * 8);
186 IRTranslator::allocateVRegs(
const Value &Val) {
187 assert(!VMap.contains(Val) &&
"Value already allocated in VMap");
188 auto *Regs = VMap.getVRegs(Val);
189 auto *
Offsets = VMap.getOffsets(Val);
193 for (
unsigned i = 0; i < SplitTys.
size(); ++i)
199 auto VRegsIt = VMap.findVRegs(Val);
200 if (VRegsIt != VMap.vregs_end())
201 return *VRegsIt->second;
204 return *VMap.getVRegs(Val);
207 auto *VRegs = VMap.getVRegs(Val);
208 auto *
Offsets = VMap.getOffsets(Val);
211 "Don't know how to create an empty vreg");
217 if (!isa<Constant>(Val)) {
218 for (
auto Ty : SplitTys)
219 VRegs->push_back(
MRI->createGenericVirtualRegister(Ty));
225 auto &
C = cast<Constant>(Val);
227 while (
auto Elt =
C.getAggregateElement(Idx++)) {
228 auto EltRegs = getOrCreateVRegs(*Elt);
229 llvm::copy(EltRegs, std::back_inserter(*VRegs));
232 assert(SplitTys.size() == 1 &&
"unexpectedly split LLT");
233 VRegs->push_back(
MRI->createGenericVirtualRegister(SplitTys[0]));
234 bool Success = translate(cast<Constant>(Val), VRegs->front());
237 MF->getFunction().getSubprogram(),
238 &MF->getFunction().getEntryBlock());
239 R <<
"unable to translate constant: " <<
ore::NV(
"Type", Val.
getType());
248 int IRTranslator::getOrCreateFrameIndex(
const AllocaInst &AI) {
249 if (FrameIndices.find(&AI) != FrameIndices.end())
250 return FrameIndices[&AI];
254 ElementSize * cast<ConstantInt>(AI.
getArraySize())->getZExtValue();
263 int &FI = FrameIndices[&AI];
264 FI = MF->getFrameInfo().CreateStackObject(Size, Alignment,
false, &AI);
268 unsigned IRTranslator::getMemOpAlignment(
const Instruction &
I) {
269 unsigned Alignment = 0;
270 Type *ValTy =
nullptr;
271 if (
const StoreInst *
SI = dyn_cast<StoreInst>(&I)) {
272 Alignment =
SI->getAlignment();
273 ValTy =
SI->getValueOperand()->getType();
274 }
else if (
const LoadInst *LI = dyn_cast<LoadInst>(&I)) {
275 Alignment = LI->getAlignment();
276 ValTy = LI->getType();
283 ValTy = AI->getCompareOperand()->
getType();
284 }
else if (
const AtomicRMWInst *AI = dyn_cast<AtomicRMWInst>(&I)) {
293 R <<
"unable to translate memop: " <<
ore::NV(
"Opcode", &I);
298 return Alignment ? Alignment : DL->getABITypeAlignment(ValTy);
303 assert(MBB &&
"BasicBlock was not encountered before");
308 assert(NewPred &&
"new predecessor must be a real MachineBasicBlock");
309 MachinePreds[Edge].push_back(NewPred);
312 bool IRTranslator::translateBinaryOp(
unsigned Opcode,
const User &U,
320 unsigned Op0 = getOrCreateVReg(*U.
getOperand(0));
321 unsigned Op1 = getOrCreateVReg(*U.
getOperand(1));
322 unsigned Res = getOrCreateVReg(U);
324 if (isa<Instruction>(U)) {
337 .
addDef(getOrCreateVReg(U))
341 return translateBinaryOp(TargetOpcode::G_FSUB, U, MIRBuilder);
346 .
addDef(getOrCreateVReg(U))
351 bool IRTranslator::translateCompare(
const User &U,
354 unsigned Op0 = getOrCreateVReg(*U.
getOperand(0));
355 unsigned Op1 = getOrCreateVReg(*U.
getOperand(1));
356 unsigned Res = getOrCreateVReg(U);
361 MIRBuilder.
buildICmp(Pred, Res, Op0, Op1);
369 auto FCmp = MIRBuilder.
buildFCmp(Pred, Res, Op0, Op1);
379 if (Ret && DL->getTypeStoreSize(Ret->getType()) == 0)
384 VRegs = getOrCreateVRegs(*Ret);
390 return CLI->lowerReturn(MIRBuilder, Ret, VRegs);
394 const BranchInst &BrInst = cast<BranchInst>(U);
418 bool IRTranslator::translateSwitch(
const User &U,
427 const SwitchInst &SwInst = cast<SwitchInst>(U);
428 const unsigned SwCondValue = getOrCreateVReg(*SwInst.
getCondition());
432 for (
auto &CaseIt : SwInst.
cases()) {
433 const unsigned CaseValueReg = getOrCreateVReg(*CaseIt.getCaseValue());
434 const unsigned Tst =
MRI->createGenericVirtualRegister(LLTi1);
437 const BasicBlock *TrueBB = CaseIt.getCaseSuccessor();
442 addMachineCFGPred({OrigBB, TrueBB}, &CurMBB);
445 MF->CreateMachineBasicBlock(SwInst.
getParent());
451 MIRBuilder.
setMBB(*FalseMBB);
456 MIRBuilder.
buildBr(DefaultMBB);
459 addMachineCFGPred({OrigBB, DefaultBB}, &CurMBB);
464 bool IRTranslator::translateIndirectBr(
const User &U,
468 const unsigned Tgt = getOrCreateVReg(*BrInst.
getAddress());
480 const LoadInst &LI = cast<LoadInst>(U);
486 if (DL->getTypeStoreSize(LI.
getType()) == 0)
493 for (
unsigned i = 0; i < Regs.
size(); ++i) {
498 unsigned BaseAlign = getMemOpAlignment(LI);
499 auto MMO = MF->getMachineMemOperand(
500 Ptr, Flags, (
MRI->getType(Regs[i]).getSizeInBits() + 7) / 8,
503 MIRBuilder.
buildLoad(Regs[i], Addr, *MMO);
522 for (
unsigned i = 0; i < Vals.
size(); ++i) {
527 unsigned BaseAlign = getMemOpAlignment(SI);
528 auto MMO = MF->getMachineMemOperand(
529 Ptr, Flags, (
MRI->getType(Vals[i]).getSizeInBits() + 7) / 8,
547 for (
auto Idx : EVI->indices())
549 }
else if (
const InsertValueInst *IVI = dyn_cast<InsertValueInst>(&U)) {
550 for (
auto Idx : IVI->indices())
557 return 8 *
static_cast<uint64_t
>(
561 bool IRTranslator::translateExtractValue(
const User &U,
569 auto &DstRegs = allocateVRegs(U);
571 for (
unsigned i = 0; i < DstRegs.size(); ++i)
572 DstRegs[i] = SrcRegs[Idx++];
577 bool IRTranslator::translateInsertValue(
const User &U,
581 auto &DstRegs = allocateVRegs(U);
585 auto InsertedIt = InsertedRegs.
begin();
587 for (
unsigned i = 0; i < DstRegs.size(); ++i) {
588 if (DstOffsets[i] >= Offset && InsertedIt != InsertedRegs.
end())
589 DstRegs[i] = *InsertedIt++;
591 DstRegs[i] = SrcRegs[i];
597 bool IRTranslator::translateSelect(
const User &U,
599 unsigned Tst = getOrCreateVReg(*U.
getOperand(0));
606 for (
unsigned i = 0; i < ResRegs.size(); ++i) {
608 MIRBuilder.
buildSelect(ResRegs[i], Tst, Op0Regs[i], Op1Regs[i]);
609 if (Cmp && isa<FPMathOperator>(Cmp)) {
610 Select->copyIRFlags(*Cmp);
617 bool IRTranslator::translateBitCast(
const User &U,
622 unsigned SrcReg = getOrCreateVReg(*U.
getOperand(0));
623 auto &Regs = *VMap.getVRegs(U);
629 Regs.push_back(SrcReg);
630 VMap.getOffsets(U)->push_back(0);
634 return translateCast(TargetOpcode::G_BITCAST, U, MIRBuilder);
637 bool IRTranslator::translateCast(
unsigned Opcode,
const User &U,
640 unsigned Res = getOrCreateVReg(U);
645 bool IRTranslator::translateGetElementPtr(
const User &U,
652 unsigned BaseReg = getOrCreateVReg(Op0);
655 Type *OffsetIRTy = DL->getIntPtrType(PtrIRTy);
661 const Value *Idx = GTI.getOperand();
662 if (
StructType *StTy = GTI.getStructTypeOrNull()) {
663 unsigned Field = cast<Constant>(Idx)->getUniqueInteger().getZExtValue();
664 Offset += DL->getStructLayout(StTy)->getElementOffset(Field);
667 uint64_t ElementSize = DL->getTypeAllocSize(GTI.getIndexedType());
671 if (
const auto *CI = dyn_cast<ConstantInt>(Idx)) {
672 Offset += ElementSize * CI->getSExtValue();
677 unsigned NewBaseReg =
MRI->createGenericVirtualRegister(PtrTy);
680 MIRBuilder.
buildGEP(NewBaseReg, BaseReg, OffsetReg);
682 BaseReg = NewBaseReg;
686 unsigned IdxReg = getOrCreateVReg(*Idx);
687 if (
MRI->getType(IdxReg) != OffsetTy) {
688 unsigned NewIdxReg =
MRI->createGenericVirtualRegister(OffsetTy);
695 unsigned GepOffsetReg;
696 if (ElementSize != 1) {
697 unsigned ElementSizeReg =
700 GepOffsetReg =
MRI->createGenericVirtualRegister(OffsetTy);
701 MIRBuilder.
buildMul(GepOffsetReg, ElementSizeReg, IdxReg);
703 GepOffsetReg = IdxReg;
705 unsigned NewBaseReg =
MRI->createGenericVirtualRegister(PtrTy);
706 MIRBuilder.
buildGEP(NewBaseReg, BaseReg, GepOffsetReg);
707 BaseReg = NewBaseReg;
712 unsigned OffsetReg = getOrCreateVReg(*
ConstantInt::get(OffsetIRTy, Offset));
713 MIRBuilder.
buildGEP(getOrCreateVReg(U), BaseReg, OffsetReg);
717 MIRBuilder.
buildCopy(getOrCreateVReg(U), BaseReg);
721 bool IRTranslator::translateMemfunc(
const CallInst &CI,
726 if (cast<PointerType>(DstTy)->getAddressSpace() != 0 ||
731 for (
int i = 0; i < 3; ++i) {
741 if(cast<PointerType>(SrcTy)->getAddressSpace() != 0)
758 void IRTranslator::getStackGuard(
unsigned DstReg,
762 auto MIB = MIRBuilder.
buildInstr(TargetOpcode::LOAD_STACK_GUARD);
765 auto &TLI = *MF->getSubtarget().getTargetLowering();
766 Value *Global = TLI.getSDagStackGuard(*MF->getFunction().getParent());
774 MF->getMachineMemOperand(MPInfo, Flags, DL->getPointerSizeInBits() / 8,
775 DL->getPointerABIAlignment(0));
776 MIB.setMemRefs({MemRef});
779 bool IRTranslator::translateOverflowIntrinsic(
const CallInst &CI,
unsigned Op,
809 if (!Address || isa<UndefValue>(Address)) {
816 "Expected inlined-at fields to agree");
837 "Expected inlined-at fields to agree");
847 auto &TLI = *MF->getSubtarget().getTargetLowering();
849 unsigned ListSize = TLI.getVaListSizeInBits(*DL) / 8;
851 MIRBuilder.
buildInstr(TargetOpcode::G_VASTART)
852 .
addUse(getOrCreateVReg(*Ptr))
863 "Expected inlined-at fields to agree");
868 }
else if (
const auto *CI = dyn_cast<Constant>(V)) {
871 unsigned Reg = getOrCreateVReg(*V);
881 return translateOverflowIntrinsic(CI, TargetOpcode::G_UADDO, MIRBuilder);
883 return translateOverflowIntrinsic(CI, TargetOpcode::G_SADDO, MIRBuilder);
885 return translateOverflowIntrinsic(CI, TargetOpcode::G_USUBO, MIRBuilder);
887 return translateOverflowIntrinsic(CI, TargetOpcode::G_SSUBO, MIRBuilder);
889 return translateOverflowIntrinsic(CI, TargetOpcode::G_UMULO, MIRBuilder);
891 return translateOverflowIntrinsic(CI, TargetOpcode::G_SMULO, MIRBuilder);
893 auto Pow = MIRBuilder.
buildInstr(TargetOpcode::G_FPOW)
894 .
addDef(getOrCreateVReg(CI))
901 auto Exp = MIRBuilder.
buildInstr(TargetOpcode::G_FEXP)
902 .
addDef(getOrCreateVReg(CI))
904 Exp->copyIRFlags(CI);
908 auto Exp2 = MIRBuilder.
buildInstr(TargetOpcode::G_FEXP2)
909 .
addDef(getOrCreateVReg(CI))
915 auto Log = MIRBuilder.
buildInstr(TargetOpcode::G_FLOG)
916 .
addDef(getOrCreateVReg(CI))
923 .
addDef(getOrCreateVReg(CI))
925 Log2->copyIRFlags(CI);
929 auto Log10 = MIRBuilder.
buildInstr(TargetOpcode::G_FLOG10)
930 .
addDef(getOrCreateVReg(CI))
936 auto Fabs = MIRBuilder.
buildInstr(TargetOpcode::G_FABS)
937 .
addDef(getOrCreateVReg(CI))
943 MIRBuilder.
buildInstr(TargetOpcode::G_INTRINSIC_TRUNC)
944 .
addDef(getOrCreateVReg(CI))
948 MIRBuilder.
buildInstr(TargetOpcode::G_INTRINSIC_ROUND)
949 .
addDef(getOrCreateVReg(CI))
954 .
addDef(getOrCreateVReg(CI))
958 FMA->copyIRFlags(CI);
963 const TargetLowering &TLI = *MF->getSubtarget().getTargetLowering();
964 unsigned Dst = getOrCreateVReg(CI);
972 auto FMA = MIRBuilder.
buildInstr(TargetOpcode::G_FMA, {Dst}, {Op0, Op1, Op2});
973 FMA->copyIRFlags(CI);
976 auto FMul = MIRBuilder.
buildInstr(TargetOpcode::G_FMUL, {Ty}, {Op0, Op1});
978 auto FAdd = MIRBuilder.
buildInstr(TargetOpcode::G_FADD, {Dst}, {FMul, Op2});
986 return translateMemfunc(CI, MIRBuilder, ID);
989 unsigned Reg = getOrCreateVReg(CI);
990 unsigned TypeID = MF->getTypeIDFor(GV);
1007 getStackGuard(getOrCreateVReg(CI), MIRBuilder);
1011 unsigned GuardVal =
MRI->createGenericVirtualRegister(PtrTy);
1012 getStackGuard(GuardVal, MIRBuilder);
1015 int FI = getOrCreateFrameIndex(*Slot);
1016 MF->getFrameInfo().setStackProtectorIndex(FI);
1019 GuardVal, getOrCreateVReg(*Slot),
1030 unsigned Opcode = isTrailing
1031 ? Cst->
isZero() ? TargetOpcode::G_CTTZ
1032 : TargetOpcode::G_CTTZ_ZERO_UNDEF
1033 : Cst->
isZero() ? TargetOpcode::G_CTLZ
1034 : TargetOpcode::G_CTLZ_ZERO_UNDEF;
1036 .
addDef(getOrCreateVReg(CI))
1042 .
addDef(getOrCreateVReg(CI))
1048 unsigned Undef =
MRI->createGenericVirtualRegister(PtrTy);
1056 .
addDef(getOrCreateVReg(CI))
1063 bool IRTranslator::translateInlineAsm(
const CallInst &CI,
1069 unsigned ExtraInfo = 0;
1082 unsigned IRTranslator::packRegs(
const Value &V,
1088 if (Regs.
size() == 1)
1091 unsigned Dst =
MRI->createGenericVirtualRegister(BigTy);
1093 for (
unsigned i = 0; i < Regs.
size(); ++i) {
1094 unsigned NewDst =
MRI->createGenericVirtualRegister(BigTy);
1095 MIRBuilder.
buildInsert(NewDst, Dst, Regs[i], Offsets[i]);
1101 void IRTranslator::unpackRegs(
const Value &V,
unsigned Src,
1106 for (
unsigned i = 0; i < Regs.
size(); ++i)
1111 const CallInst &CI = cast<CallInst>(U);
1112 auto TII = MF->getTarget().getIntrinsicInfo();
1120 return translateInlineAsm(CI, MIRBuilder);
1129 bool IsSplitType = valueIsSplit(CI);
1131 unsigned Res = IsSplitType ?
MRI->createGenericVirtualRegister(
1133 : getOrCreateVReg(CI);
1139 MF->getFrameInfo().setHasCalls(
true);
1140 bool Success = CLI->lowerCall(MIRBuilder, &CI, Res, Args, [&]() {
1145 unpackRegs(CI, Res, MIRBuilder);
1151 if (translateKnownIntrinsic(CI, ID, MIRBuilder))
1160 Res = getOrCreateVReg(CI);
1167 if (isa<MetadataAsValue>(
Arg))
1173 unpackRegs(CI, Res, MIRBuilder);
1176 const TargetLowering &TLI = *MF->getSubtarget().getTargetLowering();
1177 TargetLowering::IntrinsicInfo
Info;
1180 uint64_t
Size = Info.memVT.getStoreSize();
1182 Info.flags, Size, Info.align));
1188 bool IRTranslator::translateInvoke(
const User &U,
1198 if (isa<InlineAsm>(Callee))
1210 if (!isa<LandingPadInst>(EHPadBB->
front()))
1215 MCSymbol *BeginSymbol = Context.createTempSymbol();
1224 if (!CLI->lowerCall(MIRBuilder, &I, Res, Args,
1225 [&]() { return getOrCreateVReg(*I.getCalledValue()); }))
1228 unpackRegs(I, Res, MIRBuilder);
1230 MCSymbol *EndSymbol = Context.createTempSymbol();
1235 &ReturnMBB = getMBB(*ReturnBB);
1236 MF->addInvoke(&EHPadMBB, BeginSymbol, EndSymbol);
1239 MIRBuilder.
buildBr(ReturnMBB);
1244 bool IRTranslator::translateLandingPad(
const User &U,
1254 auto &TLI = *MF->getSubtarget().getTargetLowering();
1255 const Constant *PersonalityFn = MF->getFunction().getPersonalityFn();
1256 if (TLI.getExceptionPointerRegister(PersonalityFn) == 0 &&
1257 TLI.getExceptionSelectorRegister(PersonalityFn) == 0)
1270 .
addSym(MF->addLandingPad(&MBB));
1273 unsigned Undef =
MRI->createGenericVirtualRegister(Ty);
1277 for (
Type *Ty : cast<StructType>(LP.
getType())->elements())
1279 assert(Tys.
size() == 2 &&
"Only two-valued landingpads are supported");
1282 unsigned ExceptionReg = TLI.getExceptionPointerRegister(PersonalityFn);
1286 MBB.addLiveIn(ExceptionReg);
1288 MIRBuilder.
buildCopy(ResRegs[0], ExceptionReg);
1290 unsigned SelectorReg = TLI.getExceptionSelectorRegister(PersonalityFn);
1294 MBB.addLiveIn(SelectorReg);
1295 unsigned PtrVReg =
MRI->createGenericVirtualRegister(Tys[0]);
1296 MIRBuilder.
buildCopy(PtrVReg, SelectorReg);
1297 MIRBuilder.
buildCast(ResRegs[1], PtrVReg);
1302 bool IRTranslator::translateAlloca(
const User &U,
1304 auto &AI = cast<AllocaInst>(U);
1310 unsigned Res = getOrCreateVReg(AI);
1311 int FI = getOrCreateFrameIndex(AI);
1317 if (MF->getTarget().getTargetTriple().isOSWindows())
1325 unsigned NumElts = getOrCreateVReg(*AI.
getArraySize());
1327 Type *IntPtrIRTy = DL->getIntPtrType(AI.
getType());
1329 if (
MRI->getType(NumElts) != IntPtrTy) {
1330 unsigned ExtElts =
MRI->createGenericVirtualRegister(IntPtrTy);
1335 unsigned AllocSize =
MRI->createGenericVirtualRegister(IntPtrTy);
1338 MIRBuilder.
buildMul(AllocSize, NumElts, TySize);
1341 auto &TLI = *MF->getSubtarget().getTargetLowering();
1342 unsigned SPReg = TLI.getStackPointerRegisterToSaveRestore();
1344 unsigned SPTmp =
MRI->createGenericVirtualRegister(PtrTy);
1347 unsigned AllocTmp =
MRI->createGenericVirtualRegister(PtrTy);
1348 MIRBuilder.
buildGEP(AllocTmp, SPTmp, AllocSize);
1353 unsigned StackAlign =
1354 MF->getSubtarget().getFrameLowering()->getStackAlignment();
1355 Align =
std::max(Align, StackAlign);
1356 if (Align > StackAlign || DL->getTypeAllocSize(Ty) % StackAlign != 0) {
1360 unsigned AlignedAlloc =
MRI->createGenericVirtualRegister(PtrTy);
1362 AllocTmp = AlignedAlloc;
1366 MIRBuilder.
buildCopy(getOrCreateVReg(AI), AllocTmp);
1368 MF->getFrameInfo().CreateVariableSizedObject(Align ? Align : 1, &AI);
1369 assert(MF->getFrameInfo().hasVarSizedObjects());
1379 .
addDef(getOrCreateVReg(U))
1385 bool IRTranslator::translateInsertElement(
const User &U,
1390 unsigned Elt = getOrCreateVReg(*U.
getOperand(1));
1391 auto &Regs = *VMap.getVRegs(U);
1393 Regs.push_back(Elt);
1394 VMap.getOffsets(U)->push_back(0);
1401 unsigned Res = getOrCreateVReg(U);
1402 unsigned Val = getOrCreateVReg(*U.
getOperand(0));
1403 unsigned Elt = getOrCreateVReg(*U.
getOperand(1));
1404 unsigned Idx = getOrCreateVReg(*U.
getOperand(2));
1409 bool IRTranslator::translateExtractElement(
const User &U,
1414 unsigned Elt = getOrCreateVReg(*U.
getOperand(0));
1415 auto &Regs = *VMap.getVRegs(U);
1417 Regs.push_back(Elt);
1418 VMap.getOffsets(U)->push_back(0);
1424 unsigned Res = getOrCreateVReg(U);
1425 unsigned Val = getOrCreateVReg(*U.
getOperand(0));
1426 const auto &TLI = *MF->getSubtarget().getTargetLowering();
1427 unsigned PreferredVecIdxWidth = TLI.getVectorIdxTy(*DL).getSizeInBits();
1429 if (
auto *CI = dyn_cast<ConstantInt>(U.
getOperand(1))) {
1430 if (CI->getBitWidth() != PreferredVecIdxWidth) {
1431 APInt NewIdx = CI->getValue().sextOrTrunc(PreferredVecIdxWidth);
1433 Idx = getOrCreateVReg(*NewIdxCI);
1438 if (
MRI->getType(Idx).getSizeInBits() != PreferredVecIdxWidth) {
1446 bool IRTranslator::translateShuffleVector(
const User &U,
1448 MIRBuilder.
buildInstr(TargetOpcode::G_SHUFFLE_VECTOR)
1449 .
addDef(getOrCreateVReg(U))
1457 const PHINode &PI = cast<PHINode>(U);
1460 for (
auto Reg : getOrCreateVRegs(PI)) {
1461 auto MIB = MIRBuilder.
buildInstr(TargetOpcode::G_PHI, {
Reg}, {});
1462 Insts.push_back(MIB.getInstr());
1465 PendingPHIs.emplace_back(&PI, std::move(Insts));
1469 bool IRTranslator::translateAtomicCmpXchg(
const User &U,
1481 Type *
ValType = ResType->Type::getStructElementType(0);
1483 auto Res = getOrCreateVRegs(I);
1484 unsigned OldValRes = Res[0];
1485 unsigned SuccessRes = Res[1];
1491 OldValRes, SuccessRes, Addr, Cmp, NewVal,
1493 Flags, DL->getTypeStoreSize(ValType),
1494 getMemOpAlignment(I),
AAMDNodes(),
nullptr,
1500 bool IRTranslator::translateAtomicRMW(
const User &U,
1510 unsigned Res = getOrCreateVReg(I);
1514 unsigned Opcode = 0;
1520 Opcode = TargetOpcode::G_ATOMICRMW_XCHG;
1523 Opcode = TargetOpcode::G_ATOMICRMW_ADD;
1526 Opcode = TargetOpcode::G_ATOMICRMW_SUB;
1529 Opcode = TargetOpcode::G_ATOMICRMW_AND;
1532 Opcode = TargetOpcode::G_ATOMICRMW_NAND;
1535 Opcode = TargetOpcode::G_ATOMICRMW_OR;
1538 Opcode = TargetOpcode::G_ATOMICRMW_XOR;
1541 Opcode = TargetOpcode::G_ATOMICRMW_MAX;
1544 Opcode = TargetOpcode::G_ATOMICRMW_MIN;
1547 Opcode = TargetOpcode::G_ATOMICRMW_UMAX;
1550 Opcode = TargetOpcode::G_ATOMICRMW_UMIN;
1555 Opcode, Res, Addr, Val,
1557 Flags, DL->getTypeStoreSize(ResType),
1558 getMemOpAlignment(I),
AAMDNodes(),
nullptr,
1563 void IRTranslator::finishPendingPhis() {
1568 #endif // ifndef NDEBUG 1569 for (
auto &Phi : PendingPHIs) {
1570 const PHINode *PI = Phi.first;
1574 Verifier.setCurrentInst(PI);
1575 #endif // ifndef NDEBUG 1585 if (HandledPreds.
count(IRPred))
1588 HandledPreds.
insert(IRPred);
1590 for (
auto Pred : getMachinePredBBs({IRPred, PI->
getParent()})) {
1591 assert(Pred->isSuccessor(ComponentPHIs[0]->getParent()) &&
1592 "incorrect CFG at MachineBasicBlock level");
1593 for (
unsigned j = 0; j < ValRegs.
size(); ++j) {
1603 bool IRTranslator::valueIsSplit(
const Value &V,
1606 if (Offsets && !Offsets->
empty())
1609 return SplitTys.
size() > 1;
1612 bool IRTranslator::translate(
const Instruction &Inst) {
1616 #define HANDLE_INST(NUM, OPCODE, CLASS) \ 1617 case Instruction::OPCODE: \ 1618 return translate##OPCODE(Inst, *CurBuilder.get()); 1619 #include "llvm/IR/Instruction.def" 1625 bool IRTranslator::translate(
const Constant &
C,
unsigned Reg) {
1626 if (
auto CI = dyn_cast<ConstantInt>(&C))
1627 EntryBuilder->buildConstant(Reg, *CI);
1628 else if (
auto CF = dyn_cast<ConstantFP>(&C))
1629 EntryBuilder->buildFConstant(Reg, *CF);
1630 else if (isa<UndefValue>(C))
1631 EntryBuilder->buildUndef(Reg);
1632 else if (isa<ConstantPointerNull>(C)) {
1635 unsigned NullSize = DL->getTypeSizeInBits(C.
getType());
1638 unsigned ZeroReg = getOrCreateVReg(*ZeroVal);
1639 EntryBuilder->buildCast(Reg, ZeroReg);
1640 }
else if (
auto GV = dyn_cast<GlobalValue>(&C))
1641 EntryBuilder->buildGlobalValue(Reg, GV);
1642 else if (
auto CAZ = dyn_cast<ConstantAggregateZero>(&C)) {
1643 if (!CAZ->getType()->isVectorTy())
1646 if (CAZ->getNumElements() == 1)
1647 return translate(*CAZ->getElementValue(0u),
Reg);
1649 for (
unsigned i = 0; i < CAZ->getNumElements(); ++i) {
1650 Constant &Elt = *CAZ->getElementValue(i);
1653 EntryBuilder->buildBuildVector(Reg, Ops);
1654 }
else if (
auto CV = dyn_cast<ConstantDataVector>(&C)) {
1656 if (CV->getNumElements() == 1)
1657 return translate(*CV->getElementAsConstant(0),
Reg);
1659 for (
unsigned i = 0; i < CV->getNumElements(); ++i) {
1660 Constant &Elt = *CV->getElementAsConstant(i);
1663 EntryBuilder->buildBuildVector(Reg, Ops);
1664 }
else if (
auto CE = dyn_cast<ConstantExpr>(&C)) {
1665 switch(CE->getOpcode()) {
1666 #define HANDLE_INST(NUM, OPCODE, CLASS) \ 1667 case Instruction::OPCODE: \ 1668 return translate##OPCODE(*CE, *EntryBuilder.get()); 1669 #include "llvm/IR/Instruction.def" 1673 }
else if (
auto CV = dyn_cast<ConstantVector>(&C)) {
1674 if (CV->getNumOperands() == 1)
1675 return translate(*CV->getOperand(0),
Reg);
1677 for (
unsigned i = 0; i < CV->getNumOperands(); ++i) {
1678 Ops.
push_back(getOrCreateVReg(*CV->getOperand(i)));
1680 EntryBuilder->buildBuildVector(Reg, Ops);
1681 }
else if (
auto *BA = dyn_cast<BlockAddress>(&C)) {
1682 EntryBuilder->buildBlockAddress(Reg, BA);
1689 void IRTranslator::finalizeFunction() {
1692 PendingPHIs.clear();
1694 FrameIndices.clear();
1695 MachinePreds.clear();
1699 EntryBuilder.reset();
1709 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
1712 TPC = &getAnalysis<TargetPassConfig>();
1717 EntryBuilder = make_unique<CSEMIRBuilder>(CurMF);
1718 std::unique_ptr<CSEConfig> Config = make_unique<CSEConfig>();
1719 CSEInfo = &Wrapper.
get(std::move(Config));
1720 EntryBuilder->setCSEInfo(CSEInfo);
1721 CurBuilder = make_unique<CSEMIRBuilder>(CurMF);
1722 CurBuilder->setCSEInfo(CSEInfo);
1724 EntryBuilder = make_unique<MachineIRBuilder>();
1725 CurBuilder = make_unique<MachineIRBuilder>();
1727 CLI = MF->getSubtarget().getCallLowering();
1728 CurBuilder->
setMF(*MF);
1729 EntryBuilder->setMF(*MF);
1730 MRI = &MF->getRegInfo();
1732 ORE = llvm::make_unique<OptimizationRemarkEmitter>(&
F);
1734 assert(PendingPHIs.empty() &&
"stale PHIs");
1736 if (!DL->isLittleEndian()) {
1740 R <<
"unable to translate in big endian mode";
1745 auto FinalizeOnReturn =
make_scope_exit([
this]() { finalizeFunction(); });
1750 EntryBuilder->setMBB(*EntryBB);
1754 auto *&MBB = BBToMBB[&BB];
1756 MBB = MF->CreateMachineBasicBlock(&BB);
1760 MBB->setHasAddressTaken();
1764 EntryBB->addSuccessor(&getMBB(F.front()));
1769 if (DL->getTypeStoreSize(
Arg.
getType()) == 0)
1776 for (
auto &
Arg : F.args()) {
1777 if (
Arg.hasSwiftErrorAttr() ||
Arg.hasSwiftSelfAttr()) {
1779 F.getSubprogram(), &F.getEntryBlock());
1780 R <<
"unable to lower arguments due to swifterror/swiftself: " 1781 <<
ore::NV(
"Prototype", F.getType());
1787 if (!CLI->lowerFormalArguments(*EntryBuilder.get(),
F, VRegArgs)) {
1789 F.getSubprogram(), &F.getEntryBlock());
1790 R <<
"unable to lower arguments: " <<
ore::NV(
"Prototype", F.getType());
1795 auto ArgIt = F.arg_begin();
1796 for (
auto &VArg : VRegArgs) {
1799 if (!valueIsSplit(*ArgIt, VMap.getOffsets(*ArgIt))) {
1800 auto &VRegs = *VMap.getVRegs(cast<Value>(*ArgIt));
1801 assert(VRegs.empty() &&
"VRegs already populated?");
1802 VRegs.push_back(VArg);
1804 unpackRegs(*ArgIt, VArg, *EntryBuilder.get());
1811 if (EnableCSE && CSEInfo)
1818 #endif // ifndef NDEBUG 1824 CurBuilder->setMBB(MBB);
1828 Verifier.setCurrentInst(&Inst);
1829 #endif // ifndef NDEBUG 1830 if (translate(Inst))
1835 R <<
"unable to translate instruction: " <<
ore::NV(
"Opcode", &Inst);
1837 if (ORE->allowExtraAnalysis(
"gisel-irtranslator")) {
1838 std::string InstStrStorage;
1842 R <<
": '" << InstStr.
str() <<
"'";
1854 finishPendingPhis();
1859 assert(EntryBB->succ_size() == 1 &&
1860 "Custom BB used for lowering should have only one successor");
1863 assert(NewEntryBB.pred_size() == 1 &&
1864 "LLVM-IR entry block has a predecessor!?");
1867 NewEntryBB.splice(NewEntryBB.begin(), EntryBB, EntryBB->begin(),
1872 NewEntryBB.addLiveIn(LiveIn);
1873 NewEntryBB.sortUniqueLiveIns();
1876 EntryBB->removeSuccessor(&NewEntryBB);
1877 MF->remove(EntryBB);
1878 MF->DeleteMachineBasicBlock(EntryBB);
1880 assert(&MF->front() == &NewEntryBB &&
1881 "New entry wasn't next in the list of basic block!");
1885 SP.copyToMachineFrameInfo(MF->getFrameInfo());
void initializeIRTranslatorPass(PassRegistry &)
Return a value (possibly void), from a function.
Value * getValueOperand()
bool isIntrinsic() const
isIntrinsic - Returns true if the function's name starts with "llvm.".
A simple RAII based CSEInfo installer.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
A parsed version of the target data layout string in and methods for querying it. ...
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
This class is the base class for the comparison instructions.
static IntegerType * getInt1Ty(LLVMContext &C)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
MachineInstrBuilder buildZExtOrTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ZEXT Op, Res = G_TRUNC Op, or Res = COPY Op depending on the differing sizes...
*p = old <signed v ? old : v
iterator_range< CaseIt > cases()
Iteration adapter for range-for loops.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
This class represents an incoming formal argument to a Function.
bool doesNotAccessMemory(unsigned OpNo) const
MachineInstrBuilder buildGEP(unsigned Res, unsigned Op0, unsigned Op1)
Build and insert Res = G_GEP Op0, Op1.
DiagnosticInfoOptimizationBase::Argument NV
This represents the llvm.dbg.label instruction.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
MachineInstrBuilder buildIndirectDbgValue(unsigned Reg, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in me...
void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
MachineInstrBuilder buildSExtOrTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_SEXT Op, Res = G_TRUNC Op, or Res = COPY Op depending on the differing sizes...
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isSized(SmallPtrSetImpl< Type *> *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
void setIsEHPad(bool V=true)
Indicates the block is a landing pad.
an instruction that atomically checks whether a specified value is in a memory location, and, if it is, stores a new value there.
const StructLayout * getStructLayout(StructType *Ty) const
Returns a StructLayout object, indicating the alignment of the struct, its size, and the offsets of i...
void push_back(const T &Elt)
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
unsigned getReg() const
getReg - Returns the register number.
MachineInstrBuilder buildCast(const DstOp &Dst, const SrcOp &Src)
Build and insert an appropriate cast between two registers of equal size.
IRTranslator LLVM IR static false void reportTranslationError(MachineFunction &MF, const TargetPassConfig &TPC, OptimizationRemarkEmitter &ORE, OptimizationRemarkMissed &R)
This class represents a function call, abstracting a target machine's calling convention.
Value * getCondition() const
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID of this store instruction.
gep_type_iterator gep_type_end(const User *GEP)
const std::string & getAsmString() const
*p = old <unsigned v ? old : v
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
AtomicOrdering getOrdering() const
Returns the ordering constraint of this load instruction.
*p = old >unsigned v ? old : v
LLVM_NODISCARD detail::scope_exit< typename std::decay< Callable >::type > make_scope_exit(Callable &&F)
LLVMContext & getContext() const
All values hold a context through their type.
bool hasDLLImportStorageClass() const
BasicBlock * getSuccessor(unsigned i) const
Value * getNewValOperand()
unsigned const TargetRegisterInfo * TRI
The actual analysis pass wrapper.
An instruction for reading from memory.
void setMF(MachineFunction &MF)
an instruction that atomically reads a memory location, combines it with another value, and then stores the result back.
Value * getCondition() const
bool isVectorTy() const
True if this is an instance of VectorType.
MachineInstrBuilder buildExtract(unsigned Res, unsigned Src, uint64_t Index)
Build and insert `Res0, ...
GlobalValue * ExtractTypeInfo(Value *V)
ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V.
*p = old >signed v ? old : v
virtual bool getTgtMemIntrinsic(IntrinsicInfo &, const CallInst &, MachineFunction &, unsigned) const
Given an intrinsic, checks if on the target the intrinsic will need to map to a MemIntrinsicNode (tou...
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
AtomicOrdering getFailureOrdering() const
Returns the failure ordering constraint of this cmpxchg instruction.
bool hasSideEffects() const
Value * getArgOperand(unsigned i) const
MachineInstrBuilder buildStore(unsigned Val, unsigned Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
AnalysisUsage & addRequired()
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool isVolatile() const
Return true if this is a load from a volatile memory location.
A description of a memory reference used in the backend.
GISelCSEInfo & get(std::unique_ptr< CSEConfig > CSEOpt, bool ReCompute=false)
Takes a CSEConfig object that defines what opcodes get CSEd.
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
unsigned countOperandBundlesOfType(StringRef Name) const
Return the number of operand bundles with the tag Name attached to this instruction.
This class represents the LLVM 'select' instruction.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
unsigned getAlignment() const
Return the alignment of the memory that is being allocated by the instruction.
PointerType * getType() const
Overload to return most specific pointer type.
Class to represent struct types.
DILabel * getLabel() const
BinOp getOperation() const
const MachineInstrBuilder & addUse(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
bool isWeak() const
Return true if this cmpxchg may spuriously fail.
TypeID
Definitions of all of the base types for the Type system.
The memory access is dereferenceable (i.e., doesn't trap).
bool isVolatile() const
Return true if this is a cmpxchg from a volatile memory location.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Target-Independent Code Generator Pass Configuration Options.
INLINEASM - Represents an inline asm block.
Context object for machine code objects.
Value * getPointerOperand()
Type * getType() const
All values are typed, get the type of this value.
AtomicOrdering getSuccessOrdering() const
Returns the success ordering constraint of this cmpxchg instruction.
Class to represent array types.
MachineInstrBuilder buildAtomicRMW(unsigned Opcode, unsigned OldValRes, unsigned Addr, unsigned Val, MachineMemOperand &MMO)
Build and insert OldValRes<def> = G_ATOMICRMW_<Opcode> Addr, Val, MMO.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
iterator_range< User::op_iterator > arg_operands()
auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range))
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
An instruction for storing to memory.
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
amdgpu Simplify well known AMD library false Value * Callee
MachineInstrBuilder buildExtractVectorElement(const DstOp &Res, const SrcOp &Val, const SrcOp &Idx)
Build and insert Res = G_EXTRACT_VECTOR_ELT Val, Idx.
Value * getOperand(unsigned i) const
Analysis containing CSE Info
MachineInstrBuilder buildDbgLabel(const MDNode *Label)
Build and insert a DBG_LABEL instructions specifying that Label is given.
bool isVoidTy() const
Return true if this is 'void'.
The memory access is volatile.
bool isValidLocationForIntrinsic(const DILocation *DL) const
Check that a location is valid for this label.
const BasicBlock & getEntryBlock() const
constexpr uint64_t MinAlign(uint64_t A, uint64_t B)
A and B are either alignments or offsets.
initializer< Ty > init(const Ty &Val)
Abstract class that contains various methods for clients to notify about changes. ...
FPOpFusion::FPOpFusionMode AllowFPOpFusion
AllowFPOpFusion - This flag is set by the -fuse-fp-ops=xxx option.
The landingpad instruction holds all of the information necessary to generate correct exception handl...
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID of this rmw instruction.
unsigned const MachineRegisterInfo * MRI
Value * getCalledValue() const
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
DISubprogram * getSubprogram() const
Get the attached subprogram.
Conditional or Unconditional Branch instruction.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
Value * getAddress() const
size_t size() const
size - Get the array size.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
Value * getCompareOperand()
MachineInstrBuilder buildPtrMask(unsigned Res, unsigned Op0, uint32_t NumBits)
Build and insert Res = G_PTR_MASK Op0, NumBits.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const Instruction & front() const
Indirect Branch Instruction.
MachineInstrBuilder buildIntrinsic(Intrinsic::ID ID, unsigned Res, bool HasSideEffects)
Build and insert either a G_INTRINSIC (if HasSideEffects is false) or G_INTRINSIC_W_SIDE_EFFECTS inst...
Helper class to build MachineInstr.
BasicBlock * getDefaultDest() const
DIExpression * getExpression() const
bool isValidLocationForIntrinsic(const DILocation *DL) const
Check that a location is valid for this variable.
Represent the analysis usage information of a pass.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
MachineInstrBuilder buildInsert(unsigned Res, unsigned Src, unsigned Op, unsigned Index)
Value * getPointerOperand()
self_iterator getIterator()
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
const MachineInstrBuilder & addSym(MCSymbol *Sym, unsigned char TargetFlags=0) const
static Constant * getAllOnesValue(Type *Ty)
1 1 1 1 Always true (always folded)
MachineInstrBuilder buildBrIndirect(unsigned Tgt)
Build and insert G_BRINDIRECT Tgt.
succ_iterator succ_begin()
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID of this cmpxchg instruction.
BasicBlock * getSuccessor(unsigned i) const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const Value * getArraySize() const
Get the number of elements allocated.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
AtomicOrdering getOrdering() const
Returns the ordering constraint of this rmw instruction.
Simple wrapper that does the following.
This class contains a discriminated union of information about pointers in memory operands...
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
EVT getValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the EVT corresponding to this LLVM type.
const std::string & getConstraintString() const
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
EH_LABEL - Represents a label in mid basic block used to track locations needed for debug and excepti...
MachineInstrBuilder buildFrameIndex(unsigned Res, int Idx)
Build and insert Res = G_FRAME_INDEX Idx.
void copyIRFlags(const Instruction &I)
Copy all flags to MachineInst MIFlags.
LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
The memory access writes data.
MachineInstrBuilder buildBr(MachineBasicBlock &Dest)
Build and insert G_BR Dest.
bool hasAddressTaken() const
Returns true if there are any uses of this basic block other than direct branches, switches, etc.
MachineInstrBuilder buildConstDbgValue(const Constant &C, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instructions specifying that Variable is given by C (suitably modified b...
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
unsigned getNumOperands() const
MachineInstrBuilder buildMul(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, Optional< unsigned > Flags=None)
Build and insert Res = G_MUL Op0, Op1.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
This is the shared class of boolean and integer constants.
double Log2(double Value)
Return the log base 2 of the specified value.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool isAggregateType() const
Return true if the type is an aggregate type.
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
static uint64_t getOffsetFromIndices(const User &U, const DataLayout &DL)
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
MachineInstrBuilder buildBrCond(unsigned Tst, MachineBasicBlock &Dest)
Build and insert G_BRCOND Tst, Dest.
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
DebugLoc getDebugLoc()
Get the current instruction's debug location.
MachineInstrBuilder buildSelect(const DstOp &Res, const SrcOp &Tst, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_SELECT Tst, Op0, Op1.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
MachineInstrBuilder buildInsertVectorElement(const DstOp &Res, const SrcOp &Val, const SrcOp &Elt, const SrcOp &Idx)
Build and insert Res = G_INSERT_VECTOR_ELT Val, Elt, Idx.
unsigned getVectorNumElements() const
bool isIntPredicate() const
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Class for arbitrary precision integers.
MachineInstrBuilder buildAtomicCmpXchgWithSuccess(unsigned OldValRes, unsigned SuccessRes, unsigned Addr, unsigned CmpVal, unsigned NewVal, MachineMemOperand &MMO)
Build and insert OldValRes<def>, SuccessRes<def> = G_ATOMIC_CMPXCHG_WITH_SUCCESS Addr, CmpVal, NewVal, MMO.
static MachineOperand CreateES(const char *SymName, unsigned char TargetFlags=0)
virtual bool isFMAFasterThanFMulAndFAdd(EVT) const
Return true if an FMA operation is faster than a pair of fmul and fadd instructions.
amdgpu Simplify well known AMD library false Value Value * Arg
The memory access reads data.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Representation of each machine instruction.
Predicate getPredicate() const
Return the predicate for this instruction.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
void addObserver(GISelChangeObserver *O)
bool isVolatile() const
Return true if this is a store to a volatile memory location.
MachineInstrBuilder buildDirectDbgValue(unsigned Reg, const MDNode *Variable, const MDNode *Expr)
Build and insert a DBG_VALUE instruction expressing the fact that the associated Variable lives in Re...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
bool isInlineAsm() const
Check if this call is an inline asm statement.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MachineInstrBuilder buildFCmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert a Res = G_FCMP PredOp0, Op1.
uint64_t getElementOffset(unsigned Idx) const
void emplace_back(ArgTypes &&... Args)
static IntegerType * getInt32Ty(LLVMContext &C)
void removeObserver(GISelChangeObserver *O)
LLVM_NODISCARD bool empty() const
AtomicOrdering getOrdering() const
Returns the ordering constraint of this store instruction.
This represents the llvm.dbg.value instruction.
bool isTokenTy() const
Return true if this is 'token'.
CallingConv::ID getCallingConv() const
verify safepoint Safepoint IR Verifier
Value * getPointerOperand()
const MachineBasicBlock & getMBB() const
Getter for the basic block we currently build.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
static cl::opt< bool > EnableCSEInIRTranslator("enable-cse-in-irtranslator", cl::desc("Should enable CSE in irtranslator"), cl::Optional, cl::init(false))
SyncScope::ID getSyncScopeID() const
Returns the synchronization scope ID of this load instruction.
void setMBB(MachineBasicBlock &MBB)
Set the insertion point to the end of MBB.
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned char TargetFlags=0) const
void push_back(MachineInstr *MI)
static Constant * getZeroValueForNegation(Type *Ty)
Floating point negation must be implemented with f(x) = -0.0 - x.
Pair of physical register and lane mask.
The memory access always returns the same value (or traps).
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
DILocalVariable * getVariable() const
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool isUnconditional() const
Optional< MachineInstrBuilder > materializeGEP(unsigned &Res, unsigned Op0, const LLT &ValueTy, uint64_t Value)
Materialize and insert Res = G_GEP Op0, (G_CONSTANT Value)
static void computeValueLLTs(const DataLayout &DL, Type &Ty, SmallVectorImpl< LLT > &ValueTys, SmallVectorImpl< uint64_t > *Offsets=nullptr, uint64_t StartingOffset=0)
AsmDialect getDialect() const
This file declares the IRTranslator pass.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
FMA - Perform a * b + c with no intermediate rounding step.
uint64_t getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type...
succ_range successors(Instruction *I)
This file describes how to lower LLVM calls to machine code calls.
MachineInstrBuilder buildLoad(unsigned Res, unsigned Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
INITIALIZE_PASS_BEGIN(IRTranslator, DEBUG_TYPE, "IRTranslator LLVM IR -> MI", false, false) INITIALIZE_PASS_END(IRTranslator
Primary interface to the complete machine description for the target machine.
const MachineInstrBuilder & addDef(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
MachineInstrBuilder buildUndef(const DstOp &Res)
Build and insert Res = IMPLICIT_DEF.
Simple wrapper observer that takes several observers, and calls each one for each event...
bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size...
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned char TargetFlags=0) const
const MachineOperand & getOperand(unsigned i) const
OutputIt copy(R &&Range, OutputIt Out)
This represents the llvm.dbg.declare instruction.
Value * getPointerOperand()
Statically lint checks LLVM IR
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
int64_t getIndexedOffsetInType(Type *ElemTy, ArrayRef< Value *> Indices) const
Returns the offset from the beginning of the type for the specified indices.
bool isVolatile() const
Return true if this is a RMW on a volatile memory location.
0 0 0 0 Always false (always folded)
This file describes how to lower LLVM code to machine code.
const BasicBlock * getParent() const
virtual const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const
Returns a TargetRegisterClass used for pointer values.
an instruction to allocate memory on the stack
This instruction inserts a struct field of array element value into an aggregate value.
gep_type_iterator gep_type_begin(const User *GEP)
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.