69 #include <unordered_map>
73 using namespace PatternMatch;
74 using namespace llvm::GVNExpression;
76 #define DEBUG_TYPE "newgvn"
78 STATISTIC(NumGVNInstrDeleted,
"Number of instructions deleted");
79 STATISTIC(NumGVNBlocksDeleted,
"Number of blocks deleted");
80 STATISTIC(NumGVNOpsSimplified,
"Number of Expressions simplified");
81 STATISTIC(NumGVNPhisAllSame,
"Number of PHIs whos arguments are all the same");
83 "Maximum Number of iterations it took to converge GVN");
84 STATISTIC(NumGVNLeaderChanges,
"Number of leader changes");
85 STATISTIC(NumGVNSortedLeaderChanges,
"Number of sorted leader changes");
86 STATISTIC(NumGVNAvoidedSortedLeaderChanges,
87 "Number of avoided sorted leader changes");
89 "Number of times a member dominated it's new classes' leader");
97 namespace GVNExpression {
98 Expression::~Expression() =
default;
99 BasicExpression::~BasicExpression() =
default;
100 CallExpression::~CallExpression() =
default;
101 LoadExpression::~LoadExpression() =
default;
102 StoreExpression::~StoreExpression() =
default;
103 AggregateValueExpression::~AggregateValueExpression() =
default;
104 PHIExpression::~PHIExpression() =
default;
150 std::pair<Value *, unsigned int> NextLeader = {
nullptr, ~0U};
154 : ID(ID), RepLeader(Leader), DefiningExpr(E) {}
160 auto Val =
static_cast<uintptr_t
>(-1);
161 Val <<= PointerLikeTypeTraits<const Expression *>::NumLowBitsAvailable;
162 return reinterpret_cast<const Expression *
>(Val);
165 auto Val =
static_cast<uintptr_t
>(~1U);
166 Val <<= PointerLikeTypeTraits<const Expression *>::NumLowBitsAvailable;
167 return reinterpret_cast<const Expression *
>(Val);
175 if (LHS == getTombstoneKey() || RHS == getTombstoneKey() ||
176 LHS == getEmptyKey() || RHS == getEmptyKey())
196 std::vector<CongruenceClass *> CongruenceClasses;
197 unsigned NextCongruenceNum;
256 bool runOnFunction(
Function &
F)
override;
297 CongruenceClasses.emplace_back(result);
304 ValueToClass[Member] = CClass;
307 void initializeCongruenceClasses(
Function &
F);
348 bool eliminateInstructions(
Function &);
357 void markUsersTouched(
Value *);
362 void cleanupTables();
363 std::pair<unsigned, unsigned> assignDFSNumbers(
BasicBlock *,
unsigned);
364 void updateProcessedCount(
Value *V);
365 void verifyMemoryCongruency()
const;
374 template <
typename T>
376 if ((!isa<LoadExpression>(RHS) && !isa<StoreExpression>(RHS)) ||
377 !LHS.BasicExpression::equals(RHS)) {
379 }
else if (
const auto *
L = dyn_cast<LoadExpression>(&RHS)) {
380 if (LHS.getDefiningAccess() !=
L->getDefiningAccess())
382 }
else if (
const auto *S = dyn_cast<StoreExpression>(&RHS)) {
383 if (LHS.getDefiningAccess() != S->getDefiningAccess())
414 auto *PN = cast<PHINode>(
I);
416 new (ExpressionAllocator)
PHIExpression(PN->getNumOperands(), PHIBlock);
419 E->setType(I->getType());
420 E->setOpcode(I->getOpcode());
422 auto ReachablePhiArg = [&](
const Use &U) {
423 return ReachableBlocks.count(PN->getIncomingBlock(U));
435 return lookupOperandLeader(U, I, BBE);
444 bool AllConstant =
true;
445 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(I))
455 auto Operand = lookupOperandLeader(O, I, B);
456 AllConstant &= isa<Constant>(Operand);
463 const Expression *NewGVN::createBinaryExpression(
unsigned Opcode,
Type *
T,
484 if (
const Expression *SimplifiedE = checkSimplificationResults(E,
nullptr, V))
498 if (
auto *
C = dyn_cast<Constant>(V)) {
500 DEBUG(
dbgs() <<
"Simplified " << *I <<
" to "
501 <<
" constant " << *
C <<
"\n");
502 NumGVNOpsSimplified++;
503 assert(isa<BasicExpression>(E) &&
504 "We should always have had a basic expression here");
506 cast<BasicExpression>(
E)->deallocateOperands(ArgRecycler);
507 ExpressionAllocator.Deallocate(E);
508 return createConstantExpression(
C);
509 }
else if (isa<Argument>(V) || isa<GlobalVariable>(V)) {
511 DEBUG(
dbgs() <<
"Simplified " << *I <<
" to "
512 <<
" variable " << *V <<
"\n");
513 cast<BasicExpression>(
E)->deallocateOperands(ArgRecycler);
514 ExpressionAllocator.Deallocate(E);
515 return createVariableExpression(V);
521 DEBUG(
dbgs() <<
"Simplified " << *I <<
" to "
522 <<
" expression " << *V <<
"\n");
523 NumGVNOpsSimplified++;
524 assert(isa<BasicExpression>(E) &&
525 "We should always have had a basic expression here");
526 cast<BasicExpression>(
E)->deallocateOperands(ArgRecycler);
527 ExpressionAllocator.Deallocate(E);
538 bool AllConstant = setBasicExpressionInfo(I, E, B);
546 if (E->getOperand(0) > E->getOperand(1))
547 E->swapOperands(0, 1);
558 if (
auto *CI = dyn_cast<CmpInst>(I)) {
562 if (E->getOperand(0) > E->getOperand(1)) {
563 E->swapOperands(0, 1);
566 E->
setOpcode((CI->getOpcode() << 8) | Predicate);
574 "Wrong types on cmp instruction");
579 if (
const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
582 }
else if (isa<SelectInst>(I)) {
583 if (isa<Constant>(E->getOperand(0)) ||
587 E->getOperand(2), *
DL, TLI, DT, AC);
588 if (
const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
594 if (
const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
596 }
else if (
auto *BI = dyn_cast<BitCastInst>(I)) {
598 if (
const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
600 }
else if (isa<GetElementPtrInst>(I)) {
604 if (
const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
606 }
else if (AllConstant) {
615 for (
Value *Arg : E->operands())
619 if (
const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
627 if (
auto *II = dyn_cast<InsertValueInst>(I)) {
628 auto *E =
new (ExpressionAllocator)
630 setBasicExpressionInfo(I, E, B);
631 E->allocateIntOperands(ExpressionAllocator);
634 }
else if (
auto *EI = dyn_cast<ExtractValueInst>(I)) {
635 auto *E =
new (ExpressionAllocator)
637 setBasicExpressionInfo(EI, E, B);
638 E->allocateIntOperands(ExpressionAllocator);
653 auto Leader = lookupOperandLeader(V,
nullptr, B);
654 if (
auto *C = dyn_cast<Constant>(Leader))
655 return createConstantExpression(C);
656 return createVariableExpression(Leader);
677 setBasicExpressionInfo(CI, E, B);
684 Value *NewGVN::lookupOperandLeader(
Value *V,
const User *U,
const T &B)
const {
686 if (CC && (CC != InitialClass))
693 return Result ? Result : MA;
700 E->allocateOperands(ArgRecycler, ExpressionAllocator);
701 E->setType(LoadType);
705 E->op_push_back(lookupOperandLeader(PointerOp, LI, B));
720 E->allocateOperands(ArgRecycler, ExpressionAllocator);
746 auto *SI = cast<StoreInst>(
I);
754 cast<MemoryDef>(StoreAccess)->getDefiningAccess());
755 const Expression *OldStore = createStoreExpression(SI, StoreRHS, B);
763 return createStoreExpression(SI, StoreRHS, B);
766 return createStoreExpression(SI, StoreAccess, B);
771 auto *LI = cast<LoadInst>(
I);
780 if (isa<UndefValue>(LoadAddressLeader))
783 MemoryAccess *DefiningAccess = MSSAWalker->getClobberingMemoryAccess(I);
785 if (!MSSA->isLiveOnEntryDef(DefiningAccess)) {
786 if (
auto *MD = dyn_cast<MemoryDef>(DefiningAccess)) {
789 if (!ReachableBlocks.count(DefiningInst->
getParent()))
796 lookupMemoryAccessEquiv(DefiningAccess),
B);
803 auto *CI = cast<CallInst>(
I);
804 if (AA->doesNotAccessMemory(CI))
805 return createCallExpression(CI,
nullptr, B);
806 if (AA->onlyReadsMemory(CI)) {
807 MemoryAccess *DefiningAccess = MSSAWalker->getClobberingMemoryAccess(CI);
808 return createCallExpression(CI, lookupMemoryAccessEquiv(DefiningAccess), B);
816 DEBUG(
dbgs() <<
"Setting " << *From <<
" equivalent to ");
822 auto LookupResult = MemoryAccessEquiv.find(From);
823 bool Changed =
false;
825 if (LookupResult != MemoryAccessEquiv.end()) {
826 if (To && LookupResult->second != To) {
828 LookupResult->second = To;
832 MemoryAccessEquiv.erase(LookupResult);
837 "Memory equivalence should never change from nothing to something");
845 auto *E = cast<PHIExpression>(createPHIExpression(I));
850 bool HasUndef =
false;
854 if (isa<UndefValue>(Arg)) {
861 if (Filtered.begin() == Filtered.end()) {
862 DEBUG(
dbgs() <<
"Simplified PHI node " << *I <<
" to undef"
864 E->deallocateOperands(ArgRecycler);
865 ExpressionAllocator.Deallocate(E);
868 Value *AllSameValue = *(Filtered.begin());
872 return V == AllSameValue;
885 if (
auto *AllSameInst = dyn_cast<Instruction>(AllSameValue))
886 if (!DT->dominates(AllSameInst, I))
891 DEBUG(
dbgs() <<
"Simplified PHI node " << *I <<
" to " << *AllSameValue
893 E->deallocateOperands(ArgRecycler);
894 ExpressionAllocator.Deallocate(E);
895 if (
auto *C = dyn_cast<Constant>(AllSameValue))
896 return createConstantExpression(C);
897 return createVariableExpression(AllSameValue);
903 NewGVN::performSymbolicAggrValueEvaluation(
Instruction *I,
905 if (
auto *EI = dyn_cast<ExtractValueInst>(I)) {
907 if (II && EI->getNumIndices() == 1 && *EI->idx_begin() == 0) {
912 switch (II->getIntrinsicID()) {
913 case Intrinsic::sadd_with_overflow:
914 case Intrinsic::uadd_with_overflow:
917 case Intrinsic::ssub_with_overflow:
918 case Intrinsic::usub_with_overflow:
919 Opcode = Instruction::Sub;
921 case Intrinsic::smul_with_overflow:
922 case Intrinsic::umul_with_overflow:
923 Opcode = Instruction::Mul;
932 assert(II->getNumArgOperands() == 2 &&
933 "Expect two args for recognised intrinsics.");
934 return createBinaryExpression(Opcode, EI->getType(),
935 II->getArgOperand(0),
936 II->getArgOperand(1),
B);
941 return createAggregateValueExpression(I, B);
948 if (
auto *C = dyn_cast<Constant>(V))
949 E = createConstantExpression(C);
950 else if (isa<Argument>(V) || isa<GlobalVariable>(V)) {
951 E = createVariableExpression(V);
956 auto *I = cast<Instruction>(V);
958 case Instruction::ExtractValue:
959 case Instruction::InsertValue:
960 E = performSymbolicAggrValueEvaluation(I, B);
962 case Instruction::PHI:
963 E = performSymbolicPHIEvaluation(I, B);
966 E = performSymbolicCallEvaluation(I, B);
969 E = performSymbolicStoreEvaluation(I, B);
972 E = performSymbolicLoadEvaluation(I, B);
974 case Instruction::BitCast: {
975 E = createExpression(I, B);
979 case Instruction::FAdd:
980 case Instruction::Sub:
981 case Instruction::FSub:
982 case Instruction::Mul:
983 case Instruction::FMul:
984 case Instruction::UDiv:
985 case Instruction::SDiv:
986 case Instruction::FDiv:
987 case Instruction::URem:
988 case Instruction::SRem:
989 case Instruction::FRem:
990 case Instruction::Shl:
991 case Instruction::LShr:
992 case Instruction::AShr:
996 case Instruction::ICmp:
997 case Instruction::FCmp:
998 case Instruction::Trunc:
999 case Instruction::ZExt:
1000 case Instruction::SExt:
1001 case Instruction::FPToUI:
1002 case Instruction::FPToSI:
1003 case Instruction::UIToFP:
1004 case Instruction::SIToFP:
1005 case Instruction::FPTrunc:
1006 case Instruction::FPExt:
1007 case Instruction::PtrToInt:
1008 case Instruction::IntToPtr:
1010 case Instruction::ExtractElement:
1011 case Instruction::InsertElement:
1012 case Instruction::ShuffleVector:
1013 case Instruction::GetElementPtr:
1014 E = createExpression(I, B);
1026 bool NewGVN::isOnlyReachableViaThisEdge(
const BasicBlockEdge &E)
const {
1035 assert((!Pred || Pred == Src) &&
"No edge between these basic blocks!");
1037 return Pred !=
nullptr;
1040 void NewGVN::markUsersTouched(
Value *V) {
1043 assert(isa<Instruction>(
User) &&
"Use of value not within an instruction?");
1044 TouchedInstructions.set(InstrDFS[
User]);
1048 void NewGVN::markMemoryUsersTouched(
MemoryAccess *MA) {
1049 for (
auto U : MA->
users()) {
1050 if (
auto *MUD = dyn_cast<MemoryUseOrDef>(U))
1051 TouchedInstructions.set(InstrDFS[MUD->getMemoryInst()]);
1053 TouchedInstructions.set(InstrDFS[U]);
1061 if (
auto *I = dyn_cast<Instruction>(M))
1062 TouchedInstructions.set(InstrDFS[I]);
1063 LeaderChanges.insert(M);
1069 void NewGVN::moveValueToNewCongruenceClass(
Instruction *I,
1072 DEBUG(
dbgs() <<
"New congruence class for " << I <<
" is " << NewClass->
ID
1085 DT->properlyDominates(
1088 ++NumGVNNotMostDominatingLeader;
1089 assert(!isa<PHINode>(I) &&
1090 "New class for instruction should not be dominated by instruction");
1094 auto DFSNum = InstrDFS.lookup(I);
1095 if (DFSNum < NewClass->NextLeader.second)
1101 if (isa<StoreInst>(I)) {
1108 ValueToClass[
I] = NewClass;
1110 if (OldClass->
Members.
empty() && OldClass != InitialClass) {
1112 OldClass->
Dead =
true;
1114 <<
" from table\n");
1122 ++NumGVNLeaderChanges;
1126 if (OldClass->
Members.
size() == 1 || OldClass == InitialClass) {
1129 ++NumGVNAvoidedSortedLeaderChanges;
1133 ++NumGVNSortedLeaderChanges;
1137 std::pair<Value *, unsigned> MinDFS = {
nullptr, ~0U};
1138 for (
const auto X : OldClass->
Members) {
1139 auto DFSNum = InstrDFS.lookup(
X);
1140 if (DFSNum < MinDFS.second)
1141 MinDFS = {
X, DFSNum};
1145 markLeaderChangeTouched(OldClass);
1151 ValueToExpression[
I] =
E;
1156 assert(IClass &&
"Should have found a IClass");
1158 assert(!IClass->
Dead &&
"Found a dead class");
1161 if (
const auto *VE = dyn_cast<VariableExpression>(E)) {
1162 EClass = ValueToClass[VE->getVariableValue()];
1164 auto lookupResult = ExpressionToClass.insert({
E,
nullptr});
1167 if (lookupResult.second) {
1169 auto place = lookupResult.first;
1170 place->second = NewClass;
1173 if (
const auto *CE = dyn_cast<ConstantExpression>(E)) {
1175 }
else if (
const auto *SE = dyn_cast<StoreExpression>(E)) {
1182 assert(!isa<VariableExpression>(E) &&
1183 "VariableExpression should have been handled already");
1186 DEBUG(
dbgs() <<
"Created new congruence class for " << *I
1187 <<
" using expression " << *E <<
" at " << NewClass->
ID
1188 <<
" and leader " << *(NewClass->
RepLeader) <<
"\n");
1191 EClass = lookupResult.first->second;
1192 if (isa<ConstantExpression>(E))
1194 "Any class with a constant expression should have a "
1197 assert(EClass &&
"Somehow don't have an eclass");
1199 assert(!EClass->
Dead &&
"We accidentally looked up a dead class");
1202 bool ClassChanged = IClass != EClass;
1203 bool LeaderChanged = LeaderChanges.erase(I);
1204 if (ClassChanged || LeaderChanged) {
1205 DEBUG(
dbgs() <<
"Found class " << EClass->
ID <<
" for expression " << E
1209 moveValueToNewCongruenceClass(I, IClass, EClass);
1210 markUsersTouched(I);
1217 if (!isa<MemoryUse>(MA) && isa<StoreExpression>(
E) &&
1219 auto *DefAccess = cast<StoreExpression>(
E)->getDefiningAccess();
1220 setMemoryAccessEquivTo(MA, DefAccess != MA ? DefAccess :
nullptr);
1222 setMemoryAccessEquivTo(MA,
nullptr);
1224 markMemoryUsersTouched(MA);
1226 }
else if (
auto *SI = dyn_cast<StoreInst>(I)) {
1238 DEBUG(
dbgs() <<
"Checking store leader\n");
1241 if (EClass->
RepLeader != ProperLeader) {
1242 DEBUG(
dbgs() <<
"Store leader changed, fixing\n");
1244 markLeaderChangeTouched(EClass);
1245 markMemoryUsersTouched(MSSA->getMemoryAccess(SI));
1254 if (ReachableEdges.insert({From, To}).second) {
1256 if (ReachableBlocks.insert(To).second) {
1258 const auto &InstRange = BlockInstRange.lookup(To);
1259 TouchedInstructions.set(InstRange.first, InstRange.second);
1262 <<
" was reachable, but new edge {" <<
getBlockName(From)
1270 TouchedInstructions.set(InstrDFS[MemPhi]);
1272 auto BI = To->
begin();
1273 while (isa<PHINode>(BI)) {
1274 TouchedInstructions.set(InstrDFS[&*BI]);
1284 auto Result = lookupOperandLeader(Cond,
nullptr, B);
1285 if (isa<Constant>(Result))
1294 if ((BR = dyn_cast<BranchInst>(TI)) && BR->
isConditional()) {
1296 Value *CondEvaluated = findConditionEquivalence(Cond, B);
1297 if (!CondEvaluated) {
1298 if (
auto *I = dyn_cast<Instruction>(Cond)) {
1299 const Expression *E = createExpression(I, B);
1300 if (
const auto *CE = dyn_cast<ConstantExpression>(E)) {
1301 CondEvaluated =
CE->getConstantValue();
1303 }
else if (isa<ConstantInt>(Cond)) {
1304 CondEvaluated = Cond;
1310 if (CondEvaluated && (CI = dyn_cast<ConstantInt>(CondEvaluated))) {
1312 DEBUG(
dbgs() <<
"Condition for Terminator " << *TI
1313 <<
" evaluated to true\n");
1314 updateReachableEdge(B, TrueSucc);
1315 }
else if (CI->
isZero()) {
1316 DEBUG(
dbgs() <<
"Condition for Terminator " << *TI
1317 <<
" evaluated to false\n");
1318 updateReachableEdge(B, FalseSucc);
1321 updateReachableEdge(B, TrueSucc);
1322 updateReachableEdge(B, FalseSucc);
1324 }
else if (
auto *SI = dyn_cast<SwitchInst>(TI)) {
1331 Value *SwitchCond = SI->getCondition();
1332 Value *CondEvaluated = findConditionEquivalence(SwitchCond, B);
1334 if (CondEvaluated && isa<ConstantInt>(CondEvaluated)) {
1335 auto *CondVal = cast<ConstantInt>(CondEvaluated);
1337 auto CaseVal = SI->findCaseValue(CondVal);
1338 if (CaseVal.getCaseSuccessor() == SI->getDefaultDest()) {
1342 updateReachableEdge(B, SI->getDefaultDest());
1346 BasicBlock *TargetBlock = CaseVal.getCaseSuccessor();
1347 updateReachableEdge(B, TargetBlock);
1349 for (
unsigned i = 0, e = SI->getNumSuccessors();
i != e; ++
i) {
1351 ++SwitchEdges[TargetBlock];
1352 updateReachableEdge(B, TargetBlock);
1360 updateReachableEdge(B, TargetBlock);
1366 setMemoryAccessEquivTo(MA,
nullptr);
1374 void NewGVN::initializeCongruenceClasses(
Function &
F) {
1376 NextCongruenceNum = 2;
1379 InitialClass = createCongruenceClass(
nullptr,
nullptr);
1381 if (
auto *MP = MSSA->getMemoryAccess(&B))
1382 MemoryAccessEquiv.insert({MP, MSSA->getLiveOnEntryDef()});
1385 InitialValues.
insert(&I);
1386 ValueToClass[&
I] = InitialClass;
1394 if (isa<StoreInst>(&I)) {
1395 MemoryAccessEquiv.insert(
1396 {MSSA->getMemoryAccess(&I), MSSA->getLiveOnEntryDef()});
1397 ++InitialClass->StoreCount;
1398 assert(InitialClass->StoreCount > 0);
1402 InitialClass->Members.swap(InitialValues);
1405 for (
auto &FA : F.args())
1406 createSingletonCongruenceClass(&FA);
1409 void NewGVN::cleanupTables() {
1410 for (
unsigned i = 0, e = CongruenceClasses.size();
i != e; ++
i) {
1411 DEBUG(
dbgs() <<
"Congruence class " << CongruenceClasses[
i]->
ID <<
" has "
1412 << CongruenceClasses[
i]->Members.size() <<
" members\n");
1415 delete CongruenceClasses[
i];
1416 CongruenceClasses[
i] =
nullptr;
1419 ValueToClass.clear();
1420 ArgRecycler.clear(ExpressionAllocator);
1421 ExpressionAllocator.Reset();
1422 CongruenceClasses.clear();
1423 ExpressionToClass.clear();
1424 ValueToExpression.clear();
1425 ReachableBlocks.clear();
1426 ReachableEdges.clear();
1428 ProcessedCount.clear();
1432 InstructionsToErase.clear();
1435 BlockInstRange.clear();
1436 TouchedInstructions.clear();
1437 DominatedInstRange.clear();
1438 MemoryAccessEquiv.clear();
1441 std::pair<unsigned, unsigned> NewGVN::assignDFSNumbers(
BasicBlock *B,
1443 unsigned End = Start;
1445 InstrDFS[MemPhi] = End++;
1446 DFSToInstr.emplace_back(MemPhi);
1449 for (
auto &I : *B) {
1450 InstrDFS[&
I] = End++;
1451 DFSToInstr.emplace_back(&I);
1457 return std::make_pair(Start, End);
1460 void NewGVN::updateProcessedCount(
Value *V) {
1462 if (ProcessedCount.count(V) == 0) {
1463 ProcessedCount.insert({V, 1});
1465 ProcessedCount[V] += 1;
1466 assert(ProcessedCount[V] < 100 &&
1467 "Seem to have processed the same Value a lot");
1472 void NewGVN::valueNumberMemoryPhi(
MemoryPhi *MP) {
1480 assert(Filtered.begin() != Filtered.end() &&
1481 "We should not be processing a MemoryPhi in a completely "
1482 "unreachable block");
1486 auto LookupFunc = [&](
const Use &U) {
1487 return lookupMemoryAccessEquiv(cast<MemoryAccess>(U));
1489 auto MappedBegin =
map_iterator(Filtered.begin(), LookupFunc);
1490 auto MappedEnd =
map_iterator(Filtered.end(), LookupFunc);
1497 MappedBegin, MappedEnd,
1498 [&AllSameValue](
const MemoryAccess *V) {
return V == AllSameValue; });
1501 DEBUG(
dbgs() <<
"Memory Phi value numbered to " << *AllSameValue <<
"\n");
1503 DEBUG(
dbgs() <<
"Memory Phi value numbered to itself\n");
1505 if (setMemoryAccessEquivTo(MP, AllEqual ? AllSameValue :
nullptr))
1506 markMemoryUsersTouched(MP);
1511 void NewGVN::valueNumberInstruction(
Instruction *I) {
1512 DEBUG(
dbgs() <<
"Processing instruction " << *I <<
"\n");
1514 DEBUG(
dbgs() <<
"Skipping unused instruction\n");
1515 markInstructionForDeletion(I);
1519 const auto *Symbolized = performSymbolicEvaluation(I, I->
getParent());
1522 if (Symbolized ==
nullptr)
1523 Symbolized = createUnknownExpression(I);
1524 performCongruenceFinding(I, Symbolized);
1529 auto *Symbolized = createUnknownExpression(I);
1530 performCongruenceFinding(I, Symbolized);
1532 processOutgoingEdges(dyn_cast<TerminatorInst>(I), I->
getParent());
1538 bool NewGVN::singleReachablePHIPath(
const MemoryAccess *First,
1540 if (First == Second)
1543 if (
auto *FirstDef = dyn_cast<MemoryUseOrDef>(First)) {
1544 auto *DefAccess = FirstDef->getDefiningAccess();
1545 return singleReachablePHIPath(DefAccess, Second);
1547 auto *MP = cast<MemoryPhi>(First);
1548 auto ReachableOperandPred = [&](
const Use &U) {
1551 auto FilteredPhiArgs =
1554 std::copy(FilteredPhiArgs.begin(), FilteredPhiArgs.end(),
1555 std::back_inserter(OperandList));
1556 bool Okay = OperandList.
size() == 1;
1558 Okay =
std::equal(OperandList.begin(), OperandList.end(),
1559 OperandList.begin());
1561 return singleReachablePHIPath(cast<MemoryAccess>(OperandList[0]), Second);
1569 void NewGVN::verifyMemoryCongruency()
const {
1575 auto ReachableAccessPred =
1576 [&](
const std::pair<const MemoryAccess *, MemoryAccess *> Pair) {
1577 bool Result = ReachableBlocks.count(Pair.first->getBlock());
1580 if (
auto *MemDef = dyn_cast<MemoryDef>(Pair.first))
1586 for (
auto KV : Filtered) {
1587 assert(KV.first != KV.second &&
1588 "We added a useless equivalence to the memory equivalence table");
1591 if (!ReachableBlocks.count(KV.first->getBlock()))
1593 if (
auto *FirstMUD = dyn_cast<MemoryUseOrDef>(KV.first)) {
1595 if (FirstMUD && SecondMUD)
1596 assert((singleReachablePHIPath(FirstMUD, SecondMUD) ||
1597 ValueToClass.lookup(FirstMUD->getMemoryInst()) ==
1598 ValueToClass.lookup(SecondMUD->getMemoryInst())) &&
1599 "The instructions for these memory operations should have "
1600 "been in the same congruence class or reachable through"
1601 "a single argument phi");
1602 }
else if (
auto *FirstMP = dyn_cast<MemoryPhi>(KV.first)) {
1606 auto ReachableOperandPred = [&](
const Use &U) {
1607 return ReachableBlocks.count(FirstMP->getIncomingBlock(U)) &&
1612 auto FilteredPhiArgs =
1616 std::back_inserter(PhiOpClasses), [&](
const Use &U) {
1617 const MemoryDef *MD = cast<MemoryDef>(U);
1621 PhiOpClasses.begin()) &&
1622 "All MemoryPhi arguments should be in the same class");
1631 bool Changed =
false;
1638 MSSAWalker = MSSA->getWalker();
1642 unsigned ICount = 1;
1644 DFSToInstr.emplace_back(
nullptr);
1656 for (
auto &B : RPOT) {
1657 auto *Node = DT->getNode(B);
1658 assert(Node &&
"RPO and Dominator tree should have same reachability");
1659 RPOOrdering[Node] = ++
Counter;
1662 for (
auto &B : RPOT) {
1663 auto *Node = DT->getNode(B);
1664 if (Node->getChildren().size() > 1)
1665 std::sort(Node->begin(), Node->end(),
1667 return RPOOrdering[
A] < RPOOrdering[
B];
1672 auto DFI =
df_begin(DT->getRootNode());
1673 for (
auto DFE =
df_end(DT->getRootNode()); DFI != DFE; ++DFI) {
1675 const auto &BlockRange = assignDFSNumbers(B, ICount);
1676 BlockInstRange.insert({
B, BlockRange});
1677 ICount += BlockRange.second - BlockRange.first;
1684 if (!DFI.nodeVisited(DT->getNode(&B))) {
1685 const auto &BlockRange = assignDFSNumbers(&B, ICount);
1686 BlockInstRange.insert({&
B, BlockRange});
1687 ICount += BlockRange.second - BlockRange.first;
1691 TouchedInstructions.resize(ICount);
1692 DominatedInstRange.reserve(F.size());
1696 ExpressionToClass.reserve(ICount);
1699 const auto &InstRange = BlockInstRange.lookup(&F.getEntryBlock());
1700 TouchedInstructions.set(InstRange.first, InstRange.second);
1701 ReachableBlocks.insert(&F.getEntryBlock());
1703 initializeCongruenceClasses(F);
1705 unsigned int Iterations = 0;
1708 while (TouchedInstructions.any()) {
1711 for (
int InstrNum = TouchedInstructions.find_first(); InstrNum != -1;
1712 InstrNum = TouchedInstructions.find_next(InstrNum)) {
1713 assert(InstrNum != 0 &&
"Bit 0 should never be set, something touched an "
1714 "instruction not in the lookup table");
1715 Value *V = DFSToInstr[InstrNum];
1718 if (
auto *I = dyn_cast<Instruction>(V))
1720 else if (
auto *MP = dyn_cast<MemoryPhi>(V))
1726 if (CurrBlock != LastBlock) {
1727 LastBlock = CurrBlock;
1728 bool BlockReachable = ReachableBlocks.count(CurrBlock);
1729 const auto &CurrInstRange = BlockInstRange.lookup(CurrBlock);
1732 if (!BlockReachable) {
1733 TouchedInstructions.reset(CurrInstRange.first, CurrInstRange.second);
1734 DEBUG(
dbgs() <<
"Skipping instructions in block "
1736 <<
" because it is unreachable\n");
1739 updateProcessedCount(CurrBlock);
1742 if (
auto *MP = dyn_cast<MemoryPhi>(V)) {
1743 DEBUG(
dbgs() <<
"Processing MemoryPhi " << *MP <<
"\n");
1744 valueNumberMemoryPhi(MP);
1745 }
else if (
auto *I = dyn_cast<Instruction>(V)) {
1746 valueNumberInstruction(I);
1750 updateProcessedCount(V);
1753 TouchedInstructions.reset(InstrNum);
1756 NumGVNMaxIterations = std::max(NumGVNMaxIterations.getValue(), Iterations);
1758 verifyMemoryCongruency();
1760 Changed |= eliminateInstructions(F);
1763 for (
Instruction *ToErase : InstructionsToErase) {
1764 if (!ToErase->use_empty())
1767 ToErase->eraseFromParent();
1771 auto UnreachableBlockPred = [&](
const BasicBlock &BB) {
1772 return !ReachableBlocks.count(&BB);
1777 <<
" is unreachable\n");
1778 deleteInstructionsInBlock(&BB);
1787 if (skipFunction(F))
1789 return runGVN(F, &getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
1790 &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F),
1791 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(),
1792 &getAnalysis<AAResultsWrapperPass>().getAAResults(),
1793 &getAnalysis<MemorySSAWrapperPass>().getMSSA());
1807 bool Changed = Impl.
runGVN(F, &DT, &AC, &TLI, &AA, &MSSA);
1821 return isa<Constant>(V) || isa<Argument>(V);
1826 if (
auto *I = dyn_cast<Instruction>(V))
1878 return std::tie(DFSIn, DFSOut, LocalNum, Val, U) <
1884 void NewGVN::convertDenseToDFSOrdered(
1887 for (
auto D : Dense) {
1892 assert(BB &&
"Should have figured out a basic block for value");
1895 std::pair<int, int> DFSPair = DFSDomMap[BB];
1896 assert(DFSPair.first != -1 && DFSPair.second != -1 &&
"Invalid DFS Pair");
1897 VD.DFSIn = DFSPair.first;
1898 VD.DFSOut = DFSPair.second;
1901 if (
auto *I = dyn_cast<Instruction>(
D))
1902 VD.LocalNum = InstrDFS[
I];
1909 for (
auto &U :
D->uses()) {
1910 if (
auto *I = dyn_cast<Instruction>(U.getUser())) {
1914 if (
auto *
P = dyn_cast<PHINode>(I)) {
1915 IBlock =
P->getIncomingBlock(U);
1918 VD.LocalNum = InstrDFS.size() + 1;
1921 VD.LocalNum = InstrDFS[
I];
1923 std::pair<int, int> DFSPair = DFSDomMap[IBlock];
1924 VD.DFSIn = DFSPair.first;
1925 VD.DFSOut = DFSPair.second;
1942 if (
auto *ReplInst = dyn_cast<Instruction>(Repl)) {
1952 unsigned KnownIDs[] = {
1966 void NewGVN::deleteInstructionsInBlock(
BasicBlock *BB) {
1967 DEBUG(
dbgs() <<
" BasicBlock Dead:" << *BB);
1968 ++NumGVNBlocksDeleted;
1971 if (isa<TerminatorInst>(BB->
begin()))
1976 auto StartPoint = BB->
rbegin();
1984 if (isa<LandingPadInst>(Inst))
1988 ++NumGVNInstrDeleted;
1992 void NewGVN::markInstructionForDeletion(
Instruction *I) {
1993 DEBUG(
dbgs() <<
"Marking " << *I <<
" for deletion\n");
1994 InstructionsToErase.insert(I);
1999 DEBUG(
dbgs() <<
"Replacing " << *I <<
" with " << *V <<
"\n");
2003 markInstructionForDeletion(I);
2010 class ValueDFSStack {
2012 Value *back()
const {
return ValueStack.back(); }
2013 std::pair<int, int> dfs_back()
const {
return DFSStack.back(); }
2015 void push_back(
Value *V,
int DFSIn,
int DFSOut) {
2016 ValueStack.emplace_back(V);
2017 DFSStack.emplace_back(DFSIn, DFSOut);
2019 bool empty()
const {
return DFSStack.empty(); }
2020 bool isInScope(
int DFSIn,
int DFSOut)
const {
2023 return DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second;
2026 void popUntilDFSScope(
int DFSIn,
int DFSOut) {
2029 assert(ValueStack.size() == DFSStack.size() &&
2030 "Mismatch between ValueStack and DFSStack");
2032 !DFSStack.empty() &&
2033 !(DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second)) {
2034 DFSStack.pop_back();
2035 ValueStack.pop_back();
2045 bool NewGVN::eliminateInstructions(
Function &F) {
2069 bool AnythingReplaced =
false;
2073 DT->updateDFSNumbers();
2076 if (!ReachableBlocks.count(&B)) {
2078 for (
auto II = S->begin(); isa<PHINode>(II); ++II) {
2079 auto &Phi = cast<PHINode>(*II);
2080 DEBUG(
dbgs() <<
"Replacing incoming value of " << *II <<
" for block "
2082 <<
" with undef due to it being unreachable\n");
2083 for (
auto &Operand : Phi.incoming_values())
2084 if (Phi.getIncomingBlock(Operand) == &
B)
2099 if (CC == InitialClass || CC->
Dead)
2115 MembersLeft.
insert(Member);
2120 << *Member <<
"\n");
2124 if (
auto *I = dyn_cast<Instruction>(Member)) {
2126 "About to accidentally remove our leader");
2128 AnythingReplaced =
true;
2138 DEBUG(
dbgs() <<
"Eliminating in congruence class " << CC->
ID <<
"\n");
2146 ValueDFSStack EliminationStack;
2150 convertDenseToDFSOrdered(CC->
Members, DFSOrderedSet);
2153 std::sort(DFSOrderedSet.
begin(), DFSOrderedSet.
end());
2155 for (
auto &VD : DFSOrderedSet) {
2156 int MemberDFSIn = VD.DFSIn;
2157 int MemberDFSOut = VD.DFSOut;
2158 Value *Member = VD.Val;
2159 Use *MemberUse = VD.U;
2169 if (EliminationStack.empty()) {
2170 DEBUG(
dbgs() <<
"Elimination Stack is empty\n");
2172 DEBUG(
dbgs() <<
"Elimination Stack Top DFS numbers are ("
2173 << EliminationStack.dfs_back().first <<
","
2174 << EliminationStack.dfs_back().second <<
")\n");
2177 DEBUG(
dbgs() <<
"Current DFS numbers are (" << MemberDFSIn <<
","
2178 << MemberDFSOut <<
")\n");
2193 Member && (EliminationStack.empty() || isa<Constant>(Member));
2195 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut);
2197 if (OutOfScope || ShouldPush) {
2199 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
2200 ShouldPush |= Member && EliminationStack.empty();
2202 EliminationStack.push_back(Member, MemberDFSIn, MemberDFSOut);
2208 if (EliminationStack.empty())
2214 Value *Result = EliminationStack.back();
2217 if (MemberUse->get() == Result)
2220 DEBUG(
dbgs() <<
"Found replacement " << *Result <<
" for "
2221 << *MemberUse->get() <<
" in " << *(MemberUse->getUser())
2226 if (
auto *ReplacedInst = dyn_cast<Instruction>(MemberUse->get()))
2229 assert(isa<Instruction>(MemberUse->getUser()));
2230 MemberUse->set(Result);
2231 AnythingReplaced =
true;
2240 MembersLeft.
insert(Member);
2244 if (
auto *MemberInst = dyn_cast<Instruction>(Member)) {
2247 markInstructionForDeletion(MemberInst);
2251 MembersLeft.
insert(Member);
2256 return AnythingReplaced;
Legacy wrapper pass to provide the GlobalsAAResult object.
Value * getValueOperand()
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
A parsed version of the target data layout string in and methods for querying it. ...
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
STATISTIC(NumFunctions,"Total number of functions")
CongruenceClass(unsigned ID, Value *Leader, const Expression *E)
static bool equalsLoadStoreHelper(const T &LHS, const Expression &RHS)
This is the interface for a simple mod/ref and alias analysis over globals.
const BasicBlock * getStart() const
unsigned getNumOperands() const
This class represents a function call, abstracting a target machine's calling convention.
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
An immutable pass that tracks lazily created AssumptionCache objects.
std::pair< Value *, unsigned int > NextLeader
A cache of .assume calls within a function.
Represents a read-write access to memory, whether it is a must-alias, or a may-alias.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
const Function * getParent() const
Return the enclosing method, or null if none.
Analysis pass which computes a DominatorTree.
An instruction for reading from memory.
reverse_iterator rbegin()
virtual hash_code getHashValue() const
CongruenceClass(unsigned ID)
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
unsigned getOpcode() const
iterator begin()
Instruction iterator methods.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Legacy analysis pass which computes MemorySSA.
bool hasMemberOtherThanUs(const CongruenceClass *CC, Instruction *I)
A Use represents the edge between a Value definition and its users.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Encapsulates MemorySSA, including all data associated with memory accesses.
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
static unsigned getHashValue(const Expression *V)
Windows NT (Windows on ARM)
static BasicBlock * getBlockForValue(Value *V)
mapped_iterator< ItTy, FuncTy > map_iterator(const ItTy &I, FuncTy F)
BasicBlock * getBlock() const
void andIRFlags(const Value *V)
Logical 'and' of any supported wrapping, exact, and fast-math flags of V and this instruction...
Function Alias Analysis false
BasicBlock * getSuccessor(unsigned i) const
Base class for the actual dominator tree node.
const Expression * DefiningExpr
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
An instruction for storing to memory.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
This is the generic walker interface for walkers of MemorySSA.
FunctionPass * createNewGVNPass()
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
static const Expression * getEmptyKey()
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
unsigned getNumSuccessors() const
Return the number of successors that this terminator has.
Control flow instructions. These all have token chains.
Subclasses of this class are all able to terminate a basic block.
A set of analyses that are preserved following a run of a transformation pass.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs...ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
bool runGVN(Function &F, DominatorTree *DT, AssumptionCache *AC, TargetLibraryInfo *TLI, AliasAnalysis *AA, MemorySSA *MSSA)
BasicBlock * getSuccessor(unsigned idx) const
Return the specified successor.
Allocate memory in an ever growing pool, as if by bump-pointer.
Conditional or Unconditional Branch instruction.
df_iterator< T > df_end(const T &G)
This is an important base class in LLVM.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
A manager for alias analyses.
APInt Or(const APInt &LHS, const APInt &RHS)
Bitwise OR function for APInt.
static void patchAndReplaceAllUsesWith(Instruction *I, Value *Repl)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
APInt Xor(const APInt &LHS, const APInt &RHS)
Bitwise XOR function for APInt.
unsigned getDFSNumIn() const
getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes in the dominator tree...
Represent the analysis usage information of a pass.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
Analysis pass providing a never-invalidated alias analysis result.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
unsigned getValueID() const
Return an ID for the concrete type of this object.
static const unsigned End
This file provides the interface for LLVM's Global Value Numbering pass.
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
Value * getPointerOperand()
bool isCommutative() const
Return true if the instruction is commutative:
LLVM_NODISCARD bool empty() const
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Value * SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr)
Given operands for a SelectInst, fold the result or return null.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
static const Expression * getTombstoneKey()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const BasicBlock * getEnd() const
bool isTerminator() const
bool isConditional() const
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to 'dot...
A function analysis which provides an AssumptionCache.
Iterator for intrusive lists based on ilist_node.
This is the shared class of boolean and integer constants.
void setOpcode(unsigned opcode)
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false...
Type * getType() const
All values are typed, get the type of this value.
Provides information about what library functions are available for the current target.
bool operator<(const ValueDFS &Other) const
Value * SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr)
Given operands for a CmpInst, fold the result or return null.
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
An analysis that produces MemorySSA for a function.
PreservedAnalyses run(Function &F, AnalysisManager< Function > &AM)
Run the pass over the function.
void initializeNewGVNPass(PassRegistry &)
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
df_iterator< T > df_begin(const T &G)
static bool alwaysAvailable(Value *V)
Class that has the common methods + fields of memory uses/defs.
iterator_range< user_iterator > users()
BasicBlock * getSinglePredecessor()
Return the predecessor of this block if it has a single predecessor block.
Value * SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr)
Given operands for a BinaryOperator, fold the result or return null.
APInt And(const APInt &LHS, const APInt &RHS)
Bitwise AND function for APInt.
unsigned getDFSNumOut() const
BasicBlock * getIncomingBlock(unsigned I) const
Return incoming basic block number i.
Value * SimplifyGEPInst(Type *SrcTy, ArrayRef< Value * > Ops, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr)
Given operands for a GetElementPtrInst, fold the result or return null.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Value * getCondition() const
void emplace_back(ArgTypes &&...Args)
unsigned getAlignment() const
Return the alignment of the access that is being performed.
This file provides utility analysis objects describing memory locations.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Value * getOperand(unsigned N) const
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void preserve()
Mark an analysis as preserved.
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
static std::string getBlockName(const BasicBlock *B)
OutputIt transform(R &&Range, OutputIt d_first, UnaryPredicate P)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere...
Analysis pass providing the TargetLibraryInfo.
Instruction * getMemoryInst() const
Get the instruction that this MemoryUse represents.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Constant * ConstantFoldInstOperands(Instruction *I, ArrayRef< Constant * > Ops, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldInstOperands - Attempt to constant fold an instruction with the specified operands...
static bool isEqual(const Expression *LHS, const Expression *RHS)
Module * getParent()
Get the module that this global value is contained inside of...
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction has no side ef...
LLVM Value Representation.
succ_range successors(BasicBlock *BB)
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
static const Function * getParent(const Value *V)
The header file for the GVN pass that contains expression handling classes.
A container for analyses that lazily runs them and caches their results.
Value * SimplifyInstruction(Instruction *I, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const DominatorTree *DT=nullptr, AssumptionCache *AC=nullptr)
See if we can compute a simplified version of this instruction.
Legacy analysis pass which computes a DominatorTree.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
Represents phi nodes for memory accesses.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
void op_push_back(Value *Arg)
void swap(SmallPtrSet< PtrType, SmallSize > &RHS)
swap - Swaps the elements of two sets.
Value * getPointerOperand()
void combineMetadata(Instruction *K, const Instruction *J, ArrayRef< unsigned > KnownIDs)
Combine the metadata of two instructions so that K can replace J.
static void patchReplacementInstruction(Instruction *I, Value *Repl)
const BasicBlock * getParent() const
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
void allocateOperands(RecyclerType &Recycler, BumpPtrAllocator &Allocator)
static bool isOnlyReachableViaThisEdge(const BasicBlockEdge &E, DominatorTree *DT)
There is an edge from 'Src' to 'Dst'.
A wrapper class for inspecting calls to intrinsic functions.
bool isVoidTy() const
Return true if this is 'void'.