80 #define DEBUG_TYPE "rewrite-statepoints-for-gc" 100 #ifdef EXPENSIVE_CHECKS 103 static bool ClobberNonLive =
false;
131 bool Changed =
false;
135 if (
F.isDeclaration() ||
F.empty())
164 class RewriteStatepointsForGCLegacyPass :
public ModulePass {
170 RewriteStatepointsForGCLegacyPass() :
ModulePass(ID), Impl() {
175 bool runOnModule(
Module &M)
override {
176 bool Changed =
false;
178 getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
181 if (
F.isDeclaration() ||
F.empty())
190 getAnalysis<TargetTransformInfoWrapperPass>().getTTI(
F);
191 auto &DT = getAnalysis<DominatorTreeWrapperPass>(
F).getDomTree();
220 return new RewriteStatepointsForGCLegacyPass();
224 "rewrite-statepoints-for-gc",
225 "Make relocations explicit at statepoints",
false,
false)
229 "rewrite-statepoints-for-gc",
230 "Make relocations explicit at statepoints",
false,
false)
295 "Found non-leaf call without deopt info!");
304 GCPtrLivenessData &
Data);
315 if (
auto *PT = dyn_cast<PointerType>(T))
319 return PT->getAddressSpace() == 1;
333 if (
auto VT = dyn_cast<VectorType>(T))
345 if (
VectorType *VT = dyn_cast<VectorType>(Ty))
347 if (
ArrayType *AT = dyn_cast<ArrayType>(Ty))
375 GCPtrLivenessData &OriginalLivenessData,
CallSite CS,
376 PartiallyConstructedSafepointRecord &Result) {
383 dbgs() <<
"Live Variables:\n";
384 for (
Value *V : LiveSet)
385 dbgs() <<
" " << V->getName() <<
" " << *V <<
"\n";
389 dbgs() <<
"Number live values: " << LiveSet.size() <<
"\n";
391 Result.LiveSet = LiveSet;
406 struct BaseDefiningValueResult {
412 const bool IsKnownBase;
414 BaseDefiningValueResult(
Value *BDV,
bool IsKnownBase)
415 : BDV(BDV), IsKnownBase(IsKnownBase) {
420 assert(!MustBeBase || MustBeBase == IsKnownBase);
438 static BaseDefiningValueResult
443 if (isa<Argument>(I))
445 return BaseDefiningValueResult(I,
true);
447 if (isa<Constant>(I))
453 if (isa<LoadInst>(I))
454 return BaseDefiningValueResult(I,
true);
456 if (isa<InsertElementInst>(I))
460 return BaseDefiningValueResult(I,
false);
462 if (isa<ShuffleVectorInst>(I))
468 return BaseDefiningValueResult(I,
false);
472 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(I))
477 if (
auto *BC = dyn_cast<BitCastInst>(I))
483 if (isa<CallInst>(I) || isa<InvokeInst>(
I))
484 return BaseDefiningValueResult(I,
true);
488 assert((isa<SelectInst>(I) || isa<PHINode>(I)) &&
489 "unknown vector instruction - no base found for vector element");
490 return BaseDefiningValueResult(I,
false);
499 "Illegal to ask for the base pointer of a non-pointer type");
504 if (isa<Argument>(I))
507 return BaseDefiningValueResult(I,
true);
509 if (isa<Constant>(I)) {
520 return BaseDefiningValueResult(
524 if (
CastInst *CI = dyn_cast<CastInst>(I)) {
525 Value *
Def = CI->stripPointerCasts();
528 assert(cast<PointerType>(Def->
getType())->getAddressSpace() ==
529 cast<PointerType>(CI->getType())->getAddressSpace() &&
530 "unsupported addrspacecast");
534 assert(!isa<CastInst>(Def) &&
"shouldn't find another cast here");
538 if (isa<LoadInst>(I))
540 return BaseDefiningValueResult(I,
true);
547 switch (II->getIntrinsicID()) {
563 "interaction with the gcroot mechanism is not supported");
569 if (isa<CallInst>(I) || isa<InvokeInst>(I))
570 return BaseDefiningValueResult(I,
true);
574 assert(!isa<LandingPadInst>(I) &&
"Landing Pad is unimplemented");
576 if (isa<AtomicCmpXchgInst>(I))
580 return BaseDefiningValueResult(I,
true);
582 assert(!isa<AtomicRMWInst>(I) &&
"Xchg handled above, all others are " 583 "binary ops which don't apply to pointers");
588 if (isa<ExtractValueInst>(I))
589 return BaseDefiningValueResult(I,
true);
593 assert(!isa<InsertValueInst>(I) &&
594 "Base pointer for a struct is meaningless");
600 if (isa<ExtractElementInst>(I))
604 return BaseDefiningValueResult(I,
false);
610 assert((isa<SelectInst>(I) || isa<PHINode>(I)) &&
611 "missing instruction case in findBaseDefiningValing");
612 return BaseDefiningValueResult(I,
false);
617 Value *&Cached = Cache[
I];
623 assert(Cache[I] !=
nullptr);
631 auto Found = Cache.find(Def);
632 if (Found != Cache.end()) {
634 return Found->second;
643 if (!isa<PHINode>(V) && !isa<SelectInst>(V) &&
644 !isa<ExtractElementInst>(V) && !isa<InsertElementInst>(V) &&
645 !isa<ShuffleVectorInst>(V)) {
649 if (isa<Instruction>(V) &&
650 cast<Instruction>(V)->getMetadata(
"is_base_value")) {
669 BDVState() : BaseValue(
nullptr) {}
672 : Status(Status), BaseValue(BaseValue) {
676 explicit BDVState(
Value *BaseValue) : Status(
Base), BaseValue(BaseValue) {}
678 Status getStatus()
const {
return Status; }
679 Value *getBaseValue()
const {
return BaseValue; }
681 bool isBase()
const {
return getStatus() ==
Base; }
682 bool isUnknown()
const {
return getStatus() ==
Unknown; }
683 bool isConflict()
const {
return getStatus() == Conflict; }
686 return BaseValue == Other.BaseValue && Status == Other.Status;
689 bool operator!=(
const BDVState &other)
const {
return !(*
this == other); }
698 switch (getStatus()) {
709 OS <<
" (" << getBaseValue() <<
" - " 710 << (getBaseValue() ? getBaseValue()->getName() :
"nullptr") <<
"): ";
728 switch (LHS.getStatus()) {
733 assert(LHS.getBaseValue() &&
"can't be null");
738 if (LHS.getBaseValue() == RHS.getBaseValue()) {
739 assert(LHS == RHS &&
"equality broken!");
742 return BDVState(BDVState::Conflict);
744 assert(RHS.isConflict() &&
"only three states!");
745 return BDVState(BDVState::Conflict);
747 case BDVState::Conflict:
755 static BDVState
meetBDVState(
const BDVState &LHS,
const BDVState &RHS) {
758 "Math is wrong: meet does not commute!");
795 auto isExpectedBDVType = [](
Value *BDV) {
796 return isa<PHINode>(BDV) || isa<SelectInst>(BDV) ||
797 isa<ExtractElementInst>(BDV) || isa<InsertElementInst>(BDV) ||
798 isa<ShuffleVectorInst>(BDV);
815 while (!Worklist.
empty()) {
819 auto visitIncomingValue = [&](
Value *InVal) {
825 assert(isExpectedBDVType(Base) &&
"the only non-base values " 826 "we see should be base defining values");
827 if (States.
insert(std::make_pair(Base, BDVState())).second)
830 if (
PHINode *PN = dyn_cast<PHINode>(Current)) {
831 for (
Value *InVal : PN->incoming_values())
832 visitIncomingValue(InVal);
833 }
else if (
SelectInst *
SI = dyn_cast<SelectInst>(Current)) {
834 visitIncomingValue(
SI->getTrueValue());
835 visitIncomingValue(
SI->getFalseValue());
836 }
else if (
auto *EE = dyn_cast<ExtractElementInst>(Current)) {
837 visitIncomingValue(EE->getVectorOperand());
838 }
else if (
auto *
IE = dyn_cast<InsertElementInst>(Current)) {
839 visitIncomingValue(
IE->getOperand(0));
840 visitIncomingValue(
IE->getOperand(1));
841 }
else if (
auto *SV = dyn_cast<ShuffleVectorInst>(Current)) {
842 visitIncomingValue(SV->getOperand(0));
843 visitIncomingValue(SV->getOperand(1));
853 for (
auto Pair : States) {
854 LLVM_DEBUG(
dbgs() <<
" " << Pair.second <<
" for " << *Pair.first <<
"\n");
860 auto getStateForBDV = [&](
Value *baseValue) {
862 return BDVState(baseValue);
863 auto I = States.find(baseValue);
864 assert(I != States.end() &&
"lookup failed!");
868 bool Progress =
true;
871 const size_t OldSize = States.size();
878 for (
auto Pair : States) {
879 Value *BDV = Pair.first;
884 auto getStateForInput = [&](
Value *V)
mutable {
886 return getStateForBDV(BDV);
891 NewState =
meetBDVState(NewState, getStateForInput(
SI->getTrueValue()));
894 }
else if (
PHINode *PN = dyn_cast<PHINode>(BDV)) {
895 for (
Value *Val : PN->incoming_values())
896 NewState =
meetBDVState(NewState, getStateForInput(Val));
897 }
else if (
auto *EE = dyn_cast<ExtractElementInst>(BDV)) {
901 meetBDVState(NewState, getStateForInput(EE->getVectorOperand()));
902 }
else if (
auto *
IE = dyn_cast<InsertElementInst>(BDV)){
905 NewState =
meetBDVState(NewState, getStateForInput(
IE->getOperand(0)));
906 NewState =
meetBDVState(NewState, getStateForInput(
IE->getOperand(1)));
910 auto *SV = cast<ShuffleVectorInst>(BDV);
911 NewState =
meetBDVState(NewState, getStateForInput(SV->getOperand(0)));
912 NewState =
meetBDVState(NewState, getStateForInput(SV->getOperand(1)));
915 BDVState OldState = States[BDV];
916 if (OldState != NewState) {
918 States[BDV] = NewState;
922 assert(OldSize == States.size() &&
923 "fixed point shouldn't be adding any new nodes to state");
928 for (
auto Pair : States) {
929 LLVM_DEBUG(
dbgs() <<
" " << Pair.second <<
" for " << *Pair.first <<
"\n");
935 for (
auto Pair : States) {
937 BDVState State = Pair.second;
939 assert(!State.isUnknown() &&
"Optimistic algorithm didn't complete!");
945 if (State.isBase() && isa<ExtractElementInst>(
I) &&
946 isa<VectorType>(State.getBaseValue()->getType())) {
947 auto *EE = cast<ExtractElementInst>(
I);
952 State.getBaseValue(), EE->getIndexOperand(),
"base_ee", EE);
954 States[
I] = BDVState(BDVState::Base, BaseInst);
960 assert(!isa<InsertElementInst>(I) || State.isConflict());
962 if (!State.isConflict())
968 if (isa<PHINode>(I)) {
971 assert(NumPreds > 0 &&
"how did we reach here");
979 }
else if (
auto *EE = dyn_cast<ExtractElementInst>(I)) {
984 }
else if (
auto *
IE = dyn_cast<InsertElementInst>(I)) {
991 auto *SV = cast<ShuffleVectorInst>(
I);
998 Instruction *BaseInst = MakeBaseInstPlaceholder(I);
1001 States[
I] = BDVState(BDVState::Conflict, BaseInst);
1019 assert(States.count(BDV));
1020 Base = States[BDV].getBaseValue();
1022 assert(Base &&
"Can't be null");
1032 for (
auto Pair : States) {
1034 BDVState State = Pair.second;
1037 assert(!State.isUnknown() &&
"Optimistic algorithm didn't complete!");
1038 if (!State.isConflict())
1041 if (
PHINode *BasePHI = dyn_cast<PHINode>(State.getBaseValue())) {
1042 PHINode *PN = cast<PHINode>(BDV);
1044 for (
unsigned i = 0; i < NumPHIValues; i++) {
1057 int BlockIndex = BasePHI->getBasicBlockIndex(InBB);
1058 if (BlockIndex != -1) {
1059 Value *OldBase = BasePHI->getIncomingValue(BlockIndex);
1060 BasePHI->addIncoming(OldBase, InBB);
1063 Value *
Base = getBaseForInput(InVal,
nullptr);
1071 "Sanity -- findBaseOrBDV should be pure!");
1080 BasePHI->addIncoming(Base, InBB);
1082 assert(BasePHI->getNumIncomingValues() == NumPHIValues);
1084 dyn_cast<SelectInst>(State.getBaseValue())) {
1089 BaseSI->setTrueValue(getBaseForInput(SI->
getTrueValue(), BaseSI));
1090 BaseSI->setFalseValue(getBaseForInput(SI->
getFalseValue(), BaseSI));
1091 }
else if (
auto *BaseEE =
1092 dyn_cast<ExtractElementInst>(State.getBaseValue())) {
1093 Value *InVal = cast<ExtractElementInst>(BDV)->getVectorOperand();
1096 BaseEE->setOperand(0, getBaseForInput(InVal, BaseEE));
1097 }
else if (
auto *BaseIE = dyn_cast<InsertElementInst>(State.getBaseValue())){
1098 auto *BdvIE = cast<InsertElementInst>(BDV);
1099 auto UpdateOperand = [&](
int OperandIdx) {
1100 Value *InVal = BdvIE->getOperand(OperandIdx);
1101 Value *
Base = getBaseForInput(InVal, BaseIE);
1102 BaseIE->setOperand(OperandIdx, Base);
1107 auto *BaseSV = cast<ShuffleVectorInst>(State.getBaseValue());
1108 auto *BdvSV = cast<ShuffleVectorInst>(BDV);
1109 auto UpdateOperand = [&](
int OperandIdx) {
1110 Value *InVal = BdvSV->getOperand(OperandIdx);
1111 Value *
Base = getBaseForInput(InVal, BaseSV);
1112 BaseSV->setOperand(OperandIdx, Base);
1122 for (
auto Pair : States) {
1123 auto *BDV = Pair.first;
1124 Value *
Base = Pair.second.getBaseValue();
1129 dbgs() <<
"Updating base value cache" 1130 <<
" for: " << BDV->getName() <<
" from: " 1131 << (Cache.count(BDV) ? Cache[BDV]->getName().str() :
"none")
1132 <<
" to: " << Base->
getName() <<
"\n");
1134 if (Cache.count(BDV)) {
1136 "must be something we 'know' is a base pointer");
1140 "base relation should be stable");
1144 assert(Cache.count(Def));
1167 for (
Value *ptr : live) {
1169 assert(base &&
"failed to find base pointer");
1170 PointerToBase[ptr] = base;
1171 assert((!isa<Instruction>(base) || !isa<Instruction>(ptr) ||
1172 DT->
dominates(cast<Instruction>(base)->getParent(),
1173 cast<Instruction>(ptr)->
getParent())) &&
1174 "The base we found better dominate the derived pointer");
1182 PartiallyConstructedSafepointRecord &result) {
1187 errs() <<
"Base Pairs (w/o Relocation):\n";
1188 for (
auto &Pair : PointerToBase) {
1189 errs() <<
" derived ";
1190 Pair.first->printAsOperand(
errs(),
false);
1192 Pair.second->printAsOperand(
errs(),
false);
1197 result.PointerToBase = PointerToBase;
1204 PartiallyConstructedSafepointRecord &result);
1211 GCPtrLivenessData RevisedLivenessData;
1213 for (
size_t i = 0; i < records.
size(); i++) {
1214 struct PartiallyConstructedSafepointRecord &
info = records[i];
1236 "All PHI nodes should have been removed!");
1274 const int LiveStart,
1278 if (LiveVariables.
empty())
1283 assert(ValIt != LiveVec.
end() &&
"Val not found in LiveVec!");
1284 size_t Index = std::distance(LiveVec.
begin(), ValIt);
1285 assert(Index < LiveVec.
size() &&
"Bug in std::find?");
1297 auto getGCRelocateDecl = [&] (
Type *Ty) {
1299 auto AS = Ty->getScalarType()->getPointerAddressSpace();
1301 if (
auto *VT = dyn_cast<VectorType>(Ty))
1312 for (
unsigned i = 0; i < LiveVariables.
size(); i++) {
1315 Builder.
getInt32(LiveStart + FindIndex(LiveVariables, BasePtrs[i]));
1318 Type *Ty = LiveVariables[i]->getType();
1319 if (!TypeToDeclMap.
count(Ty))
1320 TypeToDeclMap[Ty] = getGCRelocateDecl(Ty);
1321 Value *GCRelocateDecl = TypeToDeclMap[Ty];
1325 GCRelocateDecl, {StatepointToken, BaseIdx, LiveIdx},
1337 class DeferredReplacement {
1340 bool IsDeoptimize =
false;
1342 DeferredReplacement() =
default;
1346 assert(Old != New && Old && New &&
1347 "Cannot RAUW equal values or to / from null!");
1349 DeferredReplacement
D;
1355 static DeferredReplacement createDelete(
Instruction *ToErase) {
1356 DeferredReplacement
D;
1361 static DeferredReplacement createDeoptimizeReplacement(
Instruction *Old) {
1365 "Only way to construct a deoptimize deferred replacement");
1367 DeferredReplacement
D;
1369 D.IsDeoptimize =
true;
1374 void doReplacement() {
1378 assert(OldI != NewI &&
"Disallowed at construction?!");
1379 assert((!IsDeoptimize || !New) &&
1380 "Deoptimize intrinsics are not replaced!");
1403 const char *DeoptLowering =
"deopt-lowering";
1415 return "live-through";
1422 PartiallyConstructedSafepointRecord &Result,
1423 std::vector<DeferredReplacement> &Replacements) {
1441 if (
auto TransitionBundle =
1444 TransitionArgs = TransitionBundle->Inputs;
1450 bool IsDeoptimize =
false;
1461 if (DeoptLowering.
equals(
"live-in"))
1464 assert(DeoptLowering.
equals(
"live-through") &&
"Unsupported value!");
1468 if (
Function *F = dyn_cast<Function>(CallTarget)) {
1487 IsDeoptimize =
true;
1496 StatepointID, NumPatchBytes, CallTarget, Flags, CallArgs,
1497 TransitionArgs, DeoptArgs, GCArgs,
"safepoint_token");
1522 StatepointID, NumPatchBytes, CallTarget, ToReplace->
getNormalDest(),
1523 ToReplace->
getUnwindDest(), Flags, CallArgs, TransitionArgs, DeoptArgs,
1524 GCArgs,
"statepoint_token");
1540 "can't safely insert in this block!");
1547 Result.UnwindToken = ExceptionalToken;
1557 "can't safely insert in this block!");
1564 assert(Token &&
"Should be set in one of the above branches!");
1570 Replacements.push_back(
1571 DeferredReplacement::createDeoptimizeReplacement(CS.
getInstruction()));
1573 Token->
setName(
"statepoint_token");
1588 Replacements.emplace_back(
1591 Replacements.emplace_back(
1596 Result.StatepointToken = Token;
1610 PartiallyConstructedSafepointRecord &Result,
1611 std::vector<DeferredReplacement> &Replacements) {
1612 const auto &LiveSet = Result.LiveSet;
1613 const auto &PointerToBase = Result.PointerToBase;
1617 LiveVec.
reserve(LiveSet.size());
1618 BaseVec.
reserve(LiveSet.size());
1619 for (
Value *L : LiveSet) {
1621 assert(PointerToBase.count(L));
1622 Value *
Base = PointerToBase.find(L)->second;
1641 for (
User *U : GCRelocs) {
1648 Value *Alloca = AllocaMap[OriginalValue];
1654 "Should always have one since it's not a terminator");
1656 Value *CastedRelocatedValue =
1657 Builder.CreateBitCast(Relocate,
1658 cast<AllocaInst>(Alloca)->getAllocatedType(),
1662 Store->
insertAfter(cast<Instruction>(CastedRelocatedValue));
1665 VisitedLiveValues.
insert(OriginalValue);
1676 for (
auto RematerializedValuePair: RematerializedValues) {
1677 Instruction *RematerializedValue = RematerializedValuePair.first;
1678 Value *OriginalValue = RematerializedValuePair.second;
1681 "Can not find alloca for rematerialized value");
1682 Value *Alloca = AllocaMap[OriginalValue];
1688 VisitedLiveValues.
insert(OriginalValue);
1700 int InitialAllocaNum = 0;
1702 if (isa<AllocaInst>(I))
1710 std::size_t NumRematerializedValues = 0;
1716 auto emitAllocaFor = [&](
Value *LiveValue) {
1720 AllocaMap[LiveValue] = Alloca;
1725 for (
Value *V : Live)
1729 for (
const auto &
Info : Records)
1730 for (
auto RematerializedValuePair :
Info.RematerializedValues) {
1731 Value *OriginalValue = RematerializedValuePair.second;
1732 if (AllocaMap.
count(OriginalValue) != 0)
1735 emitAllocaFor(OriginalValue);
1736 ++NumRematerializedValues;
1748 for (
const auto &
Info : Records) {
1759 if (isa<InvokeInst>(Statepoint)) {
1768 if (ClobberNonLive) {
1775 for (
auto Pair : AllocaMap) {
1777 AllocaInst *Alloca = cast<AllocaInst>(Pair.second);
1780 if (VisitedLiveValues.
count(Def)) {
1787 for (
auto *AI : ToClobber) {
1788 auto PT = cast<PointerType>(AI->getAllocatedType());
1797 if (
auto II = dyn_cast<InvokeInst>(Statepoint)) {
1798 InsertClobbersAt(&*II->getNormalDest()->getFirstInsertionPt());
1799 InsertClobbersAt(&*II->getUnwindDest()->getFirstInsertionPt());
1801 InsertClobbersAt(cast<Instruction>(Statepoint)->getNextNode());
1807 for (
auto Pair : AllocaMap) {
1809 Value *Alloca = Pair.second;
1818 if (!isa<ConstantExpr>(U)) {
1829 auto Last = std::unique(Uses.
begin(), Uses.
end());
1833 if (isa<PHINode>(
Use)) {
1844 Use->replaceUsesOfWith(Def, Load);
1852 if (
Instruction *Inst = dyn_cast<Instruction>(Def)) {
1853 if (
InvokeInst *Invoke = dyn_cast<InvokeInst>(Inst)) {
1856 BasicBlock *NormalDest = Invoke->getNormalDest();
1859 assert(!Inst->isTerminator() &&
1860 "The only terminator that can produce a value is " 1861 "InvokeInst which is handled above.");
1865 assert(isa<Argument>(Def));
1870 assert(PromotableAllocas.
size() == Live.size() + NumRematerializedValues &&
1871 "we must have the same allocas with lives");
1872 if (!PromotableAllocas.
empty()) {
1879 if (isa<AllocaInst>(I))
1881 assert(InitialAllocaNum == 0 &&
"We must not introduce any extra allocas");
1916 Func, Values,
"", &*II->getNormalDest()->getFirstInsertionPt()));
1918 Func, Values,
"", &*II->getUnwindDest()->getFirstInsertionPt()));
1924 GCPtrLivenessData OriginalLivenessData;
1926 for (
size_t i = 0; i < records.
size(); i++) {
1927 struct PartiallyConstructedSafepointRecord &
info = records[i];
1940 Value *CurrentValue) {
1944 GEP->getPointerOperand());
1947 if (
CastInst *CI = dyn_cast<CastInst>(CurrentValue)) {
1948 if (!CI->isNoopCast(CI->getModule()->getDataLayout()))
1958 return CurrentValue;
1969 if (
CastInst *CI = dyn_cast<CastInst>(Instr)) {
1970 assert(CI->isNoopCast(CI->getModule()->getDataLayout()) &&
1971 "non noop cast is found during rematerialization");
1973 Type *SrcTy = CI->getOperand(0)->getType();
1978 Type *ValTy =
GEP->getSourceElementType();
1984 if (!
GEP->hasAllConstantIndices())
2003 for (
unsigned i = 0; i < PhiNum; i++)
2009 for (
unsigned i = 0; i < PhiNum; i++) {
2012 if (CIVI == CurrentIncomingValues.
end())
2014 BasicBlock *CurrentIncomingBB = CIVI->second;
2026 PartiallyConstructedSafepointRecord &
Info,
2028 const unsigned int ChainLengthThreshold = 10;
2034 for (
Value *LiveValue: Info.LiveSet) {
2037 assert(Info.PointerToBase.count(LiveValue));
2038 Value *RootOfChain =
2043 if ( ChainToBase.
size() == 0 ||
2044 ChainToBase.
size() > ChainLengthThreshold)
2049 if (RootOfChain != Info.PointerToBase[LiveValue]) {
2052 if (!OrigRootPhi || !AlternateRootPhi)
2068 assert(Info.LiveSet.count(AlternateRootPhi));
2087 LiveValuesToBeDeleted.
push_back(LiveValue);
2097 auto rematerializeChain = [&ChainToBase](
2106 assert(isa<GetElementPtrInst>(Instr) || isa<CastInst>(Instr));
2110 ClonedValue->
setName(Instr->getName() +
".remat");
2114 if (LastClonedValue) {
2122 "incorrect use in rematerialization chain");
2125 assert(OpValue != RootOfChain && OpValue != AlternateLiveBase);
2134 if (RootOfChain != AlternateLiveBase)
2138 LastClonedValue = ClonedValue;
2142 return LastClonedValue;
2150 Instruction *RematerializedValue = rematerializeChain(
2151 InsertBefore, RootOfChain, Info.PointerToBase[LiveValue]);
2152 Info.RematerializedValues[RematerializedValue] = LiveValue;
2161 Instruction *NormalRematerializedValue = rematerializeChain(
2162 NormalInsertBefore, RootOfChain, Info.PointerToBase[LiveValue]);
2163 Instruction *UnwindRematerializedValue = rematerializeChain(
2164 UnwindInsertBefore, RootOfChain, Info.PointerToBase[LiveValue]);
2166 Info.RematerializedValues[NormalRematerializedValue] = LiveValue;
2167 Info.RematerializedValues[UnwindRematerializedValue] = LiveValue;
2172 for (
auto LiveValue: LiveValuesToBeDeleted) {
2173 Info.LiveSet.remove(LiveValue);
2182 std::set<CallSite> Uniqued;
2183 Uniqued.insert(ToUpdate.
begin(), ToUpdate.
end());
2184 assert(Uniqued.size() == ToUpdate.
size() &&
"no duplicates please!");
2215 "support for FCA unimplemented");
2236 for (
size_t i = 0; i < Records.size(); i++) {
2237 PartiallyConstructedSafepointRecord &
info = Records[i];
2255 Holders.reserve(Holders.size() + Records.size());
2256 for (
size_t i = 0; i < Records.size(); i++) {
2257 PartiallyConstructedSafepointRecord &
Info = Records[i];
2260 for (
auto Pair : Info.PointerToBase)
2272 for (
auto &
Info : Records) {
2273 errs() <<
"Base Pairs: (w/Relocation)\n";
2274 for (
auto Pair :
Info.PointerToBase) {
2275 errs() <<
" derived ";
2276 Pair.first->printAsOperand(
errs(),
false);
2278 Pair.second->printAsOperand(
errs(),
false);
2292 for (
auto &
Info : Records)
2293 for (
auto &BasePair :
Info.PointerToBase)
2294 if (isa<Constant>(BasePair.second))
2295 Info.LiveSet.remove(BasePair.first);
2298 CI->eraseFromParent();
2305 for (
size_t i = 0; i < Records.size(); i++)
2311 std::vector<DeferredReplacement> Replacements;
2319 for (
size_t i = 0; i < Records.size(); i++)
2324 for (
auto &PR : Replacements)
2327 Replacements.clear();
2329 for (
auto &
Info : Records) {
2338 Info.LiveSet.clear();
2339 Info.PointerToBase.clear();
2344 for (
size_t i = 0; i < Records.size(); i++) {
2345 PartiallyConstructedSafepointRecord &
Info = Records[i];
2361 "statepoint must be reachable or liveness is meaningless");
2363 if (!isa<Instruction>(V))
2366 auto *LiveInst = cast<Instruction>(V);
2368 "unreachable values should never be live");
2370 "basic SSA liveness expectation violated by liveness analysis");
2378 for (
auto *Ptr : Live)
2380 "must be a gc pointer type");
2384 return !Records.empty();
2388 template <
typename AttrHolder>
2392 if (AH.getDereferenceableBytes(Index))
2394 AH.getDereferenceableBytes(Index)));
2395 if (AH.getDereferenceableOrNullBytes(Index))
2397 AH.getDereferenceableOrNullBytes(Index)));
2402 AH.setAttributes(AH.getAttributes().removeAttributes(Ctx, Index, R));
2409 if (isa<PointerType>(
A.getType()))
2421 if (!isa<LoadInst>(I) && !isa<StoreInst>(I))
2466 if (
auto *II = dyn_cast<IntrinsicInst>(&I))
2468 InvariantStartInstructions.
push_back(II);
2480 for (
int i = 0, e = CS.
arg_size(); i != e; i++)
2483 if (isa<PointerType>(CS.
getType()))
2489 for (
auto *II : InvariantStartInstructions) {
2491 II->eraseFromParent();
2500 const auto &FunctionGCName = F.
getGC();
2501 const StringRef StatepointExampleName(
"statepoint-example");
2503 return (StatepointExampleName == FunctionGCName) ||
2504 (CoreCLRName == FunctionGCName);
2525 "need function body to rewrite statepoints in");
2549 if (NeedsRewrite(I)) {
2555 "no unreachable blocks expected");
2561 if (ParsePointNeeded.
empty())
2569 if (BB.getUniquePredecessor()) {
2588 if (
auto *BI = dyn_cast<BranchInst>(TI))
2589 if (BI->isConditional())
2590 return dyn_cast<Instruction>(BI->getCondition());
2596 if (
auto *Cond = getConditionInst(TI))
2599 if (isa<ICmpInst>(Cond) && Cond->hasOneUse()) {
2601 Cond->moveBefore(TI);
2626 if (isa<PHINode>(I))
2630 for (
Value *V : I.operands()) {
2632 "support for FCA unimplemented");
2652 for (
auto &I : *Succ) {
2659 "support for FCA unimplemented");
2679 for (
Value *V : Live) {
2680 if (
auto *I = dyn_cast<Instruction>(V)) {
2684 if (TermOkay && TI == I)
2687 "basic SSA liveness expectation violated by liveness analysis");
2704 GCPtrLivenessData &Data) {
2710 Data.LiveSet[&BB].clear();
2715 assert(!Data.LiveSet[&BB].count(
Kill) &&
"live set contains kill");
2720 Data.LiveIn[&BB] = Data.LiveSet[&BB];
2721 Data.LiveIn[&BB].set_union(Data.LiveOut[&BB]);
2722 Data.LiveIn[&BB].set_subtract(Data.KillSet[&BB]);
2723 if (!Data.LiveIn[&BB].empty())
2728 while (!Worklist.
empty()) {
2734 const auto OldLiveOutSize = LiveOut.
size();
2736 assert(Data.LiveIn.count(Succ));
2740 if (OldLiveOutSize == LiveOut.
size()) {
2746 Data.LiveOut[BB] = LiveOut;
2753 assert(Data.LiveIn.count(BB));
2756 if (OldLiveIn.size() != LiveTmp.
size()) {
2757 Data.LiveIn[BB] = LiveTmp;
2775 assert(Data.LiveOut.count(BB));
2784 LiveOut.remove(Inst);
2785 Out.insert(LiveOut.begin(), LiveOut.end());
2790 PartiallyConstructedSafepointRecord &
Info) {
2797 for (
auto V : Updated)
2798 if (Info.PointerToBase.insert({V, V}).second) {
2800 "Can't find base for unexpected live value!");
2805 for (
auto V : Updated)
2806 assert(Info.PointerToBase.count(V) &&
2807 "Must be able to find base for live value!");
2813 for (
auto KVPair : Info.PointerToBase)
2814 if (!Updated.count(KVPair.first))
2815 ToErase.
insert(KVPair.first);
2817 for (
auto *V : ToErase)
2818 Info.PointerToBase.erase(V);
2821 for (
auto KVPair : Info.PointerToBase)
2822 assert(Updated.count(KVPair.first) &&
"record for non-live value");
2825 Info.LiveSet = Updated;
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
static void findLiveReferences(Function &F, DominatorTree &DT, ArrayRef< CallSite > toUpdate, MutableArrayRef< struct PartiallyConstructedSafepointRecord > records)
A parsed version of the target data layout string in and methods for querying it. ...
static void unique_unsorted(SmallVectorImpl< T > &Vec)
Implement a unique function which doesn't require we sort the input vector.
static void computeLiveOutSeed(BasicBlock *BB, SetVector< Value *> &LiveTmp)
static bool isHandledGCPointerType(Type *T)
static cl::opt< bool, true > ClobberNonLiveOverride("rs4gc-clobber-non-live", cl::location(ClobberNonLive), cl::Hidden)
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
MapVector< Value *, Value * > DefiningValueMapTy
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents an incoming formal argument to a Function.
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
static Value * findBaseDefiningValueCached(Value *I, DefiningValueMapTy &Cache)
Returns the base defining value for this value.
static bool AreEquivalentPhiNodes(PHINode &OrigRootPhi, PHINode &AlternateRootPhi)
unsigned arg_size() const
static BDVState meetBDVStateImpl(const BDVState &LHS, const BDVState &RHS)
static bool insertParsePoints(Function &F, DominatorTree &DT, TargetTransformInfo &TTI, SmallVectorImpl< CallSite > &ToUpdate)
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM_NODISCARD T pop_back_val()
This class represents lattice values for constants.
Instruction * StatepointToken
The new gc.statepoint instruction itself.
size_type size() const
Determine the number of elements in the SetVector.
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
static void stripInvalidMetadataFromInstruction(Instruction &I)
Certain metadata on instructions are invalid after running RS4GC.
Instruction * UnwindToken
Instruction to which exceptional gc relocates are attached Makes it easier to iterate through them du...
A Module instance is used to store all the information related to an LLVM module. ...
void dropUnknownNonDebugMetadata(ArrayRef< unsigned > KnownIDs)
Drop all unknown metadata except for debug locations.
StatepointDirectives parseStatepointDirectivesFromAttrs(AttributeList AS)
Parse out statepoint directives from the function attributes present in AS.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
static void checkBasicSSA(DominatorTree &DT, SetVector< Value *> &Live, Instruction *TI, bool TermOkay=false)
Check that the items in 'Live' dominate 'TI'.
void push_back(const T &Elt)
static ConstantAggregateZero * get(Type *Ty)
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
bool removeUnreachableBlocks(Function &F, LazyValueInfo *LVI=nullptr, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
static void rematerializeLiveValues(CallSite CS, PartiallyConstructedSafepointRecord &Info, TargetTransformInfo &TTI)
static StringRef getDeoptLowering(CallSite CS)
This class represents a function call, abstracting a target machine's calling convention.
INITIALIZE_PASS_BEGIN(RewriteStatepointsForGCLegacyPass, "rewrite-statepoints-for-gc", "Make relocations explicit at statepoints", false, false) INITIALIZE_PASS_END(RewriteStatepointsForGCLegacyPass
DominatorTree & getDomTree()
Flush DomTree updates and return DomTree.
MapVector< BasicBlock *, SetVector< Value * > > KillSet
Values defined in this block.
const Value * getTrueValue() const
Analysis pass providing the TargetTransformInfo.
This instruction constructs a fixed permutation of two input vectors.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", Instruction *InsertBefore=nullptr, Instruction *MDFrom=nullptr)
MapVector< BasicBlock *, SetVector< Value * > > LiveSet
Values used in this block (and thus live); does not included values killed within this block...
LLVMContext & getContext() const
All values hold a context through their type.
static void stripNonValidAttributesFromPrototype(Function &F)
MapVector< BasicBlock *, SetVector< Value * > > LiveIn
Values live into this basic block (i.e.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
This class implements a map that also provides access to all stored values in a deterministic order...
Analysis pass which computes a DominatorTree.
static void makeStatepointExplicitImpl(const CallSite CS, const SmallVectorImpl< Value *> &BasePtrs, const SmallVectorImpl< Value *> &LiveVariables, PartiallyConstructedSafepointRecord &Result, std::vector< DeferredReplacement > &Replacements)
An instruction for reading from memory.
reverse_iterator rbegin()
AttrBuilder & addAttribute(Attribute::AttrKind Val)
Add an attribute to the builder.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
bool isVectorTy() const
True if this is an instance of VectorType.
static void stripNonValidDataFromBody(Function &F)
static BaseDefiningValueResult findBaseDefiningValueOfVector(Value *I)
Return a base defining value for the 'Index' element of the given vector instruction 'I'...
void reserve(size_type N)
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const
Return true if the attribute exists at the given index.
static void computeLiveInValues(DominatorTree &DT, Function &F, GCPtrLivenessData &Data)
Compute the live-in set for every basic block in the function.
iterator begin()
Instruction iterator methods.
unsigned getAllocaAddrSpace() const
AnalysisUsage & addRequired()
static InsertElementInst * Create(Value *Vec, Value *NewElt, Value *Idx, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
#define INITIALIZE_PASS_DEPENDENCY(depName)
amdgpu Simplify well known AMD library false Value Value const Twine & Name
CallSiteTy::arg_iterator gc_args_begin() const
static void relocationViaAlloca(Function &F, DominatorTree &DT, ArrayRef< Value *> Live, ArrayRef< PartiallyConstructedSafepointRecord > Records)
Do all the relocation update via allocas and mem2reg.
This class represents the LLVM 'select' instruction.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
This is the base class for all instructions that perform data casts.
'undef' values are things that do not have specified contents.
static bool isKnownBaseResult(Value *V)
Given the result of a call to findBaseDefiningValue, or findBaseOrBDV, is it known to be a base point...
TailCallKind getTailCallKind() const
Class to represent struct types.
LLVMContext & getContext() const
Get the global data context.
static Value * findBasePointer(Value *I, DefiningValueMapTy &Cache)
For a given value or instruction, figure out what base ptr its derived from.
A Use represents the edge between a Value definition and its users.
Value * getDerivedPtr() const
static Value * findRematerializableChainToBasePointer(SmallVectorImpl< Instruction *> &ChainToBase, Value *CurrentValue)
static bool isGCPointerType(Type *T)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
static void makeStatepointExplicit(DominatorTree &DT, CallSite CS, PartiallyConstructedSafepointRecord &Result, std::vector< DeferredReplacement > &Replacements)
This file contains the simple types necessary to represent the attributes associated with functions a...
AttributeSet getRetAttributes() const
The attributes for the ret value are returned.
InstrTy * getInstruction() const
void setName(const Twine &Name)
Change the name of the value.
bool remove(const value_type &X)
Remove an item from the set vector.
void initializeRewriteStatepointsForGCLegacyPassPass(PassRegistry &)
LLVMContext & getContext() const
Retrieve the LLVM context.
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
ValTy * getCalledValue() const
Return the pointer to function that is being called.
static cl::opt< bool > PrintLiveSet("spp-print-liveset", cl::Hidden, cl::init(false))
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following: ...
Type * getType() const
All values are typed, get the type of this value.
bool insert(const value_type &X)
Insert a new element into the SetVector.
CallSiteTy::arg_iterator gc_args_end() const
const T & getValue() const LLVM_LVALUE_FUNCTION
const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
Class to represent array types.
This class represents a no-op cast from one type to another.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
AttrBuilder & remove(const AttrBuilder &B)
Remove the attributes from the builder.
const std::string & getGC() const
An instruction for storing to memory.
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
ModulePass * createRewriteStatepointsForGCLegacyPass()
StatepointLiveSetTy LiveSet
The set of values known to be live across this safepoint.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Function * getDeclaration(Module *M, ID id, ArrayRef< Type *> Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
Analysis containing CSE Info
static unsigned chainToBasePointerCost(SmallVectorImpl< Instruction *> &Chain, TargetTransformInfo &TTI)
SetVector< Value * > StatepointLiveSetTy
void replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
bool isCall() const
Return true if a CallInst is enclosed.
iterator find(const_arg_type_t< KeyT > Val)
Optional< OperandBundleUse > getOperandBundle(StringRef Name) const
static SetVector< Value * > computeKillSet(BasicBlock *BB)
bool isVoidTy() const
Return true if this is 'void'.
const BasicBlock & getEntryBlock() const
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata *> MDs)
BasicBlock * SplitBlockPredecessors(BasicBlock *BB, ArrayRef< BasicBlock *> Preds, const char *Suffix, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool PreserveLCSSA=false)
This method introduces at least one new basic block into the function and moves some of the predecess...
CallInst * CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes, Value *ActualCallee, ArrayRef< Value *> CallArgs, ArrayRef< Value *> DeoptArgs, ArrayRef< Value *> GCArgs, const Twine &Name="")
Create a call to the experimental.gc.statepoint intrinsic to start a new statepoint sequence...
initializer< Ty > init(const Ty &Val)
Type * getReturnType() const
Returns the type of the ret val.
static void RemoveNonValidAttrAtIndex(LLVMContext &Ctx, AttrHolder &AH, unsigned Index)
const Instruction * getFirstNonPHI() const
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
A set of analyses that are preserved following a run of a transformation pass.
static AttributeSet get(LLVMContext &C, const AttrBuilder &B)
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
static ArrayRef< Use > GetDeoptBundleOperands(ImmutableCallSite CS)
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction...
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
size_t size() const
size - Get the array size.
This function has undefined behavior.
This is an important base class in LLVM.
bool set_union(const STy &S)
Compute This := This u S, return whether 'This' changed.
static void analyzeParsePointLiveness(DominatorTree &DT, GCPtrLivenessData &OriginalLivenessData, CallSite CS, PartiallyConstructedSafepointRecord &Result)
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
bool hasFnAttr(Attribute::AttrKind Kind) const
Return true if this function has the given attribute.
static cl::opt< unsigned > RematerializationThreshold("spp-rematerialization-threshold", cl::Hidden, cl::init(6))
Value * getIncomingValueForBlock(const BasicBlock *BB) const
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...
static AttributeList legalizeCallAttributes(AttributeList AL)
std::pair< iterator, bool > insert(const ValueT &V)
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
bool runOnFunction(Function &F, DominatorTree &, TargetTransformInfo &, const TargetLibraryInfo &)
Optional< uint32_t > NumPatchBytes
InvokeInst * CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef< Value *> InvokeArgs, ArrayRef< Value *> DeoptArgs, ArrayRef< Value *> GCArgs, const Twine &Name="")
Create an invoke to the experimental.gc.statepoint intrinsic to start a new statepoint sequence...
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
RematerializedValueMapTy RematerializedValues
Record live values we are rematerialized instead of relocating.
void setCallingConv(CallingConv::ID CC)
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
A specialization of it's base class for read-write access to a gc.statepoint.
Interval::pred_iterator pred_end(Interval *I)
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
bool callsGCLeafFunction(ImmutableCallSite CS, const TargetLibraryInfo &TLI)
Return true if the CallSite CS calls a gc leaf function.
self_iterator getIterator()
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
static void insertRelocationStores(iterator_range< Value::user_iterator > GCRelocs, DenseMap< Value *, Value *> &AllocaMap, DenseSet< Value *> &VisitedLiveValues)
static void insertRematerializationStores(const RematerializedValueMapTy &RematerializedValues, DenseMap< Value *, Value *> &AllocaMap, DenseSet< Value *> &VisitedLiveValues)
static void stripNonValidData(Module &M)
The IR fed into RewriteStatepointsForGC may have had attributes and metadata implying dereferenceabil...
void setTailCallKind(TailCallKind TCK)
const Function * getFunction() const
Return the function this instruction belongs to.
static bool containsGCPtrType(Type *Ty)
Returns true if this type contains a gc pointer whether we know how to handle that type or not...
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs, and aliases.
iterator erase(const_iterator CI)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Attribute getAttribute(unsigned Index, Attribute::AttrKind Kind) const
Return the attribute object that exists at the given index.
static void findLiveSetAtInst(Instruction *inst, GCPtrLivenessData &Data, StatepointLiveSetTy &out)
Given results from the dataflow liveness computation, find the set of live Values at a particular ins...
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
static Value * findBaseOrBDV(Value *I, DefiningValueMapTy &Cache)
Return a base pointer for this value if known.
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.
void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
static bool shouldRewriteStatepointsIn(Function &F)
Returns true if this function should be rewritten by this pass.
bool isInvoke() const
Return true if a InvokeInst is enclosed.
void sort(IteratorTy Start, IteratorTy End)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
BasicBlock * getNormalDest() const
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
static cl::opt< bool > PrintBasePointers("spp-print-base-pointers", cl::Hidden, cl::init(false))
static cl::opt< bool > AllowStatepointWithNoDeoptInfo("rs4gc-allow-statepoint-with-no-deopt-info", cl::Hidden, cl::init(true))
A SetVector that performs no allocations if smaller than a certain size.
ValTy * getArgument(unsigned ArgNo) const
AttrBuilder & removeAttribute(Attribute::AttrKind Val)
Remove an attribute from the builder.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
static BDVState meetBDVState(const BDVState &LHS, const BDVState &RHS)
bool dominates(const Instruction *Def, const Use &U) const
Return true if Def dominates a use in User.
Module.h This file contains the declarations for the Module class.
Provides information about what library functions are available for the current target.
static void insertUseHolderAfter(CallSite &CS, const ArrayRef< Value *> Values, SmallVectorImpl< CallInst *> &Holders)
Insert holders so that each Value is obviously live through the entire lifetime of the call...
Indicates that this statepoint is a transition from GC-aware code to code that is not GC-aware...
LLVM_NODISCARD T pop_back_val()
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static BasicBlock * normalizeForInvokeSafepoint(BasicBlock *BB, BasicBlock *InvokeParent, DominatorTree &DT)
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
unsigned getNumIncomingValues() const
Return the number of incoming edges.
AttributeList getAttributes() const
Return the parameter attributes for this call.
static const Function * getCalledFunction(const Value *V, bool LookThroughBitCast, bool &IsNoBuiltin)
void set_subtract(const STy &S)
Compute This := This - B TODO: We should be able to use set_subtract from SetOperations.h, but SetVector interface is inconsistent with DenseSet.
Value handle that asserts if the Value is deleted.
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.
static bool ClobberNonLive
A range adaptor for a pair of iterators.
Class to represent vector types.
static std::string suffixed_name_or(Value *V, StringRef Suffix, StringRef DefaultName)
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
MapVector< AssertingVH< Instruction >, AssertingVH< Value > > RematerializedValueMapTy
bool isStatepointDirectiveAttr(Attribute Attr)
Return true if the Attr is an attribute that is a statepoint directive.
Optional< uint64_t > StatepointID
iterator_range< user_iterator > users()
static const uint64_t DefaultStatepointID
void FoldSingleEntryPHINodes(BasicBlock *BB, MemoryDependenceResults *MemDep=nullptr)
We know that BB has one predecessor.
iterator insert(iterator I, T &&Elt)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
const Value * getFalseValue() const
amdgpu Simplify well known AMD library false Value Value * Arg
Call sites that get wrapped by a gc.statepoint (currently only in RewriteStatepointsForGC and potenti...
bool operator!=(uint64_t V1, const APInt &V2)
static void CreateGCRelocates(ArrayRef< Value *> LiveVariables, const int LiveStart, ArrayRef< Value *> BasePtrs, Instruction *StatepointToken, IRBuilder<> Builder)
Helper function to place all gc relocates necessary for the given statepoint.
unsigned getNumUses() const
This method computes the number of uses of this Value.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
bool hasGC() const
hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm to use during code generatio...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
static cl::opt< bool > PrintLiveSetSize("spp-print-liveset-size", cl::Hidden, cl::init(false))
bool empty() const
Return true if the builder contains no target-independent attributes.
LLVM_NODISCARD bool empty() const
StringRef getValueAsString() const
Return the attribute's value as a string.
CallingConv::ID getCallingConv() const
StringRef getName() const
Return a constant reference to the value's name.
static bool isUnhandledGCPointerType(Type *Ty)
Establish a view to a call site for examination.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction...
unsigned pred_size(const BasicBlock *BB)
Get the number of predecessors of BB.
CallInst * CreateGCResult(Instruction *Statepoint, Type *ResultType, const Twine &Name="")
Create a call to the experimental.gc.result intrinsic to extract the result from a call wrapped in a ...
bool empty() const
Determine if the SetVector is empty or not.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
static void findBasePointers(const StatepointLiveSetTy &live, MapVector< Value *, Value *> &PointerToBase, DominatorTree *DT, DefiningValueMapTy &DVCache)
iterator_range< value_op_iterator > operand_values()
void setAttributes(AttributeList A)
Set the parameter attributes for this call.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
ilist_iterator< OptionsT, !IsReverse, IsConst > getReverse() const
Get a reverse iterator to the same node.
void preserve()
Mark an analysis as preserved.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value *> Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Type * getType() const
Return the type of the instruction that generated this call site.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
bool isStatepoint(ImmutableCallSite CS)
FunTy * getCalledFunction() const
Return the function being called if this is a direct call, otherwise return null (if it's an indirect...
Analysis pass providing the TargetLibraryInfo.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
BasicBlock * getUnwindDest() const
Represents calls to the gc.relocate intrinsic.
Mark the deopt arguments associated with the statepoint as only being "live-in".
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
A vector that has set insertion semantics.
succ_range successors(Instruction *I)
static VectorType * get(Type *ElementType, unsigned NumElements)
This static method is the primary way to construct an VectorType.
static void recomputeLiveInValues(GCPtrLivenessData &RevisedLivenessData, CallSite CS, PartiallyConstructedSafepointRecord &result)
Given an updated version of the dataflow liveness results, update the liveset and base pointer maps f...
static const Function * getParent(const Value *V)
AttributeSet getFnAttributes() const
The function attributes are returned.
iterator_range< arg_iterator > gc_args() const
range adapter for gc arguments
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
MapVector< BasicBlock *, SetVector< Value * > > LiveOut
Values live out of this basic block (i.e.
This class implements an extremely fast bulk output stream that can only output to a stream...
void PromoteMemToReg(ArrayRef< AllocaInst *> Allocas, DominatorTree &DT, AssumptionCache *AC=nullptr)
Promote the specified list of alloca instructions into scalar registers, inserting PHI nodes as appro...
unsigned gcArgsStartIdx() const
StringRef - Represent a constant reference to a string, i.e.
inst_range instructions(Function *F)
A container for analyses that lazily runs them and caches their results.
const LandingPadInst * getLandingPadInst() const
Return the landingpad instruction associated with the landing pad.
Legacy analysis pass which computes a DominatorTree.
AttributeList getAttributes() const
Get the parameter attributes of the call.
bool operator==(uint64_t V1, const APInt &V2)
MapVector< Value *, Value * > PointerToBase
Mapping from live pointers to a base-defining-value.
void setIncomingValue(unsigned i, Value *V)
bool isEmpty() const
Return true if there are no attributes.
InstListType::reverse_iterator reverse_iterator
MDNode * createMutableTBAAAccessTag(MDNode *Tag)
Return mutable version of the given mutable or immutable TBAA access tag.
LocationClass< Ty > location(Ty &L)
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute >> Attrs)
Create an AttributeList with the specified parameters in it.
iterator_range< arg_iterator > args()
bool empty() const
empty - Check if the array is empty.
A wrapper class for inspecting calls to intrinsic functions.
const BasicBlock * getParent() const
an instruction to allocate memory on the stack
static BaseDefiningValueResult findBaseDefiningValue(Value *I)
Helper function for findBasePointer - Will return a value which either a) defines the base pointer fo...
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.