: Allocator(InfoCache.Allocator), Functions(Functions),
InfoCache(InfoCache), CGUpdater(CGUpdater), Allowed(Allowed),
DeleteFns(DeleteFns), RewriteSignatures(RewriteSignatures),
- MaxFixpointIterations(None), OREGetter(None), PassName("") {}
+ MaxFixpointIterations(None), OREGetter(None), PassName("") {}
/// Constructor
///
///
/// If \p LivenessAA is not provided it is queried.
bool isAssumedDead(const AbstractAttribute &AA, const AAIsDead *LivenessAA,
+ bool &UsedAssumedInformation,
bool CheckBBLivenessOnly = false,
DepClassTy DepClass = DepClassTy::OPTIONAL);
///
/// If \p LivenessAA is not provided it is queried.
bool isAssumedDead(const Instruction &I, const AbstractAttribute *QueryingAA,
- const AAIsDead *LivenessAA,
+ const AAIsDead *LivenessAA, bool &UsedAssumedInformation,
bool CheckBBLivenessOnly = false,
DepClassTy DepClass = DepClassTy::OPTIONAL);
///
/// If \p FnLivenessAA is not provided it is queried.
bool isAssumedDead(const Use &U, const AbstractAttribute *QueryingAA,
- const AAIsDead *FnLivenessAA,
+ const AAIsDead *FnLivenessAA, bool &UsedAssumedInformation,
bool CheckBBLivenessOnly = false,
DepClassTy DepClass = DepClassTy::OPTIONAL);
///
/// If \p FnLivenessAA is not provided it is queried.
bool isAssumedDead(const IRPosition &IRP, const AbstractAttribute *QueryingAA,
- const AAIsDead *FnLivenessAA,
+ const AAIsDead *FnLivenessAA, bool &UsedAssumedInformation,
bool CheckBBLivenessOnly = false,
DepClassTy DepClass = DepClassTy::OPTIONAL);
bool checkForAllInstructions(function_ref<bool(Instruction &)> Pred,
const AbstractAttribute &QueryingAA,
const ArrayRef<unsigned> &Opcodes,
+ bool &UsedAssumedInformation,
bool CheckBBLivenessOnly = false,
bool CheckPotentiallyDead = false);
/// See checkForAllCallLikeInstructions(...) for more information.
bool checkForAllCallLikeInstructions(function_ref<bool(Instruction &)> Pred,
const AbstractAttribute &QueryingAA,
+ bool &UsedAssumedInformation,
bool CheckBBLivenessOnly = false,
bool CheckPotentiallyDead = false) {
- return checkForAllInstructions(Pred, QueryingAA,
- {(unsigned)Instruction::Invoke,
- (unsigned)Instruction::CallBr,
- (unsigned)Instruction::Call},
- CheckBBLivenessOnly, CheckPotentiallyDead);
+ return checkForAllInstructions(
+ Pred, QueryingAA,
+ {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
+ (unsigned)Instruction::Call},
+ UsedAssumedInformation, CheckBBLivenessOnly, CheckPotentiallyDead);
}
/// Check \p Pred on all Read/Write instructions.
/// to memory present in the information cache and return true if \p Pred
/// holds on all of them.
bool checkForAllReadWriteInstructions(function_ref<bool(Instruction &)> Pred,
- AbstractAttribute &QueryingAA);
+ AbstractAttribute &QueryingAA,
+ bool &UsedAssumedInformation);
/// Create a shallow wrapper for \p F such that \p F has internal linkage
/// afterwards. It also sets the original \p F 's name to anonymous
bool Attributor::isAssumedDead(const AbstractAttribute &AA,
const AAIsDead *FnLivenessAA,
+ bool &UsedAssumedInformation,
bool CheckBBLivenessOnly, DepClassTy DepClass) {
const IRPosition &IRP = AA.getIRPosition();
if (!Functions.count(IRP.getAnchorScope()))
return false;
- return isAssumedDead(IRP, &AA, FnLivenessAA, CheckBBLivenessOnly, DepClass);
+ return isAssumedDead(IRP, &AA, FnLivenessAA, UsedAssumedInformation,
+ CheckBBLivenessOnly, DepClass);
}
bool Attributor::isAssumedDead(const Use &U,
const AbstractAttribute *QueryingAA,
const AAIsDead *FnLivenessAA,
+ bool &UsedAssumedInformation,
bool CheckBBLivenessOnly, DepClassTy DepClass) {
Instruction *UserI = dyn_cast<Instruction>(U.getUser());
if (!UserI)
return isAssumedDead(IRPosition::value(*U.get()), QueryingAA, FnLivenessAA,
- CheckBBLivenessOnly, DepClass);
+ UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
if (auto *CB = dyn_cast<CallBase>(UserI)) {
// For call site argument uses we can check if the argument is
const IRPosition &CSArgPos =
IRPosition::callsite_argument(*CB, CB->getArgOperandNo(&U));
return isAssumedDead(CSArgPos, QueryingAA, FnLivenessAA,
- CheckBBLivenessOnly, DepClass);
+ UsedAssumedInformation, CheckBBLivenessOnly,
+ DepClass);
}
} else if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
- return isAssumedDead(RetPos, QueryingAA, FnLivenessAA, CheckBBLivenessOnly,
- DepClass);
+ return isAssumedDead(RetPos, QueryingAA, FnLivenessAA,
+ UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
} else if (PHINode *PHI = dyn_cast<PHINode>(UserI)) {
BasicBlock *IncomingBB = PHI->getIncomingBlock(U);
return isAssumedDead(*IncomingBB->getTerminator(), QueryingAA, FnLivenessAA,
- CheckBBLivenessOnly, DepClass);
+ UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
}
return isAssumedDead(IRPosition::value(*UserI), QueryingAA, FnLivenessAA,
- CheckBBLivenessOnly, DepClass);
+ UsedAssumedInformation, CheckBBLivenessOnly, DepClass);
}
bool Attributor::isAssumedDead(const Instruction &I,
const AbstractAttribute *QueryingAA,
const AAIsDead *FnLivenessAA,
+ bool &UsedAssumedInformation,
bool CheckBBLivenessOnly, DepClassTy DepClass) {
const IRPosition::CallBaseContext *CBCtx =
QueryingAA ? QueryingAA->getCallBaseContext() : nullptr;
FnLivenessAA->isAssumedDead(&I)) {
if (QueryingAA)
recordDependence(*FnLivenessAA, *QueryingAA, DepClass);
+ if (!FnLivenessAA->isKnownDead(&I))
+ UsedAssumedInformation = true;
return true;
}
if (IsDeadAA.isAssumedDead()) {
if (QueryingAA)
recordDependence(IsDeadAA, *QueryingAA, DepClass);
+ if (!IsDeadAA.isKnownDead())
+ UsedAssumedInformation = true;
return true;
}
bool Attributor::isAssumedDead(const IRPosition &IRP,
const AbstractAttribute *QueryingAA,
const AAIsDead *FnLivenessAA,
+ bool &UsedAssumedInformation,
bool CheckBBLivenessOnly, DepClassTy DepClass) {
Instruction *CtxI = IRP.getCtxI();
if (CtxI &&
- isAssumedDead(*CtxI, QueryingAA, FnLivenessAA,
+ isAssumedDead(*CtxI, QueryingAA, FnLivenessAA, UsedAssumedInformation,
/* CheckBBLivenessOnly */ true,
CheckBBLivenessOnly ? DepClass : DepClassTy::OPTIONAL))
return true;
if (IsDeadAA->isAssumedDead()) {
if (QueryingAA)
recordDependence(*IsDeadAA, *QueryingAA, DepClass);
+ if (!IsDeadAA->isKnownDead())
+ UsedAssumedInformation = true;
return true;
}
continue;
LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << **U << " in "
<< *U->getUser() << "\n");
- if (isAssumedDead(*U, &QueryingAA, LivenessAA,
+ bool UsedAssumedInformation = false;
+ if (isAssumedDead(*U, &QueryingAA, LivenessAA, UsedAssumedInformation,
/* CheckBBLivenessOnly */ false, LivenessDepClass)) {
LLVM_DEBUG(dbgs() << "[Attributor] Dead use, skip!\n");
continue;
const Use &U = *Uses[u];
LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << *U << " in "
<< *U.getUser() << "\n");
- if (isAssumedDead(U, QueryingAA, nullptr, /* CheckBBLivenessOnly */ true)) {
+ bool UsedAssumedInformation = false;
+ if (isAssumedDead(U, QueryingAA, nullptr, UsedAssumedInformation,
+ /* CheckBBLivenessOnly */ true)) {
LLVM_DEBUG(dbgs() << "[Attributor] Dead use, skip!\n");
continue;
}
Attributor *A, InformationCache::OpcodeInstMapTy &OpcodeInstMap,
function_ref<bool(Instruction &)> Pred, const AbstractAttribute *QueryingAA,
const AAIsDead *LivenessAA, const ArrayRef<unsigned> &Opcodes,
- bool CheckBBLivenessOnly = false, bool CheckPotentiallyDead = false) {
+ bool &UsedAssumedInformation, bool CheckBBLivenessOnly = false,
+ bool CheckPotentiallyDead = false) {
for (unsigned Opcode : Opcodes) {
// Check if we have instructions with this opcode at all first.
auto *Insts = OpcodeInstMap.lookup(Opcode);
// Skip dead instructions.
if (A && !CheckPotentiallyDead &&
A->isAssumedDead(IRPosition::value(*I), QueryingAA, LivenessAA,
- CheckBBLivenessOnly))
+ UsedAssumedInformation, CheckBBLivenessOnly))
continue;
if (!Pred(*I))
bool Attributor::checkForAllInstructions(function_ref<bool(Instruction &)> Pred,
const AbstractAttribute &QueryingAA,
const ArrayRef<unsigned> &Opcodes,
+ bool &UsedAssumedInformation,
bool CheckBBLivenessOnly,
bool CheckPotentiallyDead) {
auto &OpcodeInstMap =
InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
if (!checkForAllInstructionsImpl(this, OpcodeInstMap, Pred, &QueryingAA,
- LivenessAA, Opcodes, CheckBBLivenessOnly,
- CheckPotentiallyDead))
+ LivenessAA, Opcodes, UsedAssumedInformation,
+ CheckBBLivenessOnly, CheckPotentiallyDead))
return false;
return true;
}
bool Attributor::checkForAllReadWriteInstructions(
- function_ref<bool(Instruction &)> Pred, AbstractAttribute &QueryingAA) {
+ function_ref<bool(Instruction &)> Pred, AbstractAttribute &QueryingAA,
+ bool &UsedAssumedInformation) {
const Function *AssociatedFunction =
QueryingAA.getIRPosition().getAssociatedFunction();
for (Instruction *I :
InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
// Skip dead instructions.
- if (isAssumedDead(IRPosition::value(*I), &QueryingAA, &LivenessAA))
+ if (isAssumedDead(IRPosition::value(*I), &QueryingAA, &LivenessAA,
+ UsedAssumedInformation))
continue;
if (!Pred(*I))
else
MaxFixedPointIterations = SetFixpointIterations;
-
SmallVector<AbstractAttribute *, 32> ChangedAAs;
SetVector<AbstractAttribute *> Worklist, InvalidAAs;
Worklist.insert(DG.SyntheticRoot.begin(), DG.SyntheticRoot.end());
continue;
// Skip dead code.
- if (isAssumedDead(*AA, nullptr, /* CheckBBLivenessOnly */ true))
+ bool UsedAssumedInformation = false;
+ if (isAssumedDead(*AA, nullptr, UsedAssumedInformation,
+ /* CheckBBLivenessOnly */ true))
continue;
// Check if the manifest debug counter that allows skipping manifestation of
// AAs
auto &AAState = AA.getState();
ChangeStatus CS = ChangeStatus::UNCHANGED;
- if (!isAssumedDead(AA, nullptr, /* CheckBBLivenessOnly */ true))
+ bool UsedAssumedInformation = false;
+ if (!isAssumedDead(AA, nullptr, UsedAssumedInformation,
+ /* CheckBBLivenessOnly */ true))
CS = AA.update(*this);
if (DV.empty()) {
// Forbid must-tail calls for now.
// TODO:
+ bool UsedAssumedInformation = false;
auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
if (!checkForAllInstructionsImpl(nullptr, OpcodeInstMap, InstPred, nullptr,
- nullptr, {Instruction::Call})) {
+ nullptr, {Instruction::Call},
+ UsedAssumedInformation)) {
LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite due to instructions\n");
return false;
}
auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
bool Success;
+ bool UsedAssumedInformation = false;
Success = checkForAllInstructionsImpl(
nullptr, OpcodeInstMap, CallSitePred, nullptr, nullptr,
{(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
- (unsigned)Instruction::Call});
+ (unsigned)Instruction::Call},
+ UsedAssumedInformation);
(void)Success;
assert(Success && "Expected the check call to be successful!");
};
Success = checkForAllInstructionsImpl(
nullptr, OpcodeInstMap, LoadStorePred, nullptr, nullptr,
- {(unsigned)Instruction::Load, (unsigned)Instruction::Store});
+ {(unsigned)Instruction::Load, (unsigned)Instruction::Store},
+ UsedAssumedInformation);
(void)Success;
assert(Success && "Expected the check call to be successful!");
}
"Expected liveness in the presence of instructions!");
for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
BasicBlock *IncomingBB = PHI->getIncomingBlock(u);
+ bool UsedAssumedInformation = false;
if (A.isAssumedDead(*IncomingBB->getTerminator(), &QueryingAA,
- LivenessAA,
+ LivenessAA, UsedAssumedInformation,
/* CheckBBLivenessOnly */ true)) {
AnyDead = true;
continue;
return false;
};
- if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes))
+ bool UsedAssumedInformation = false;
+ if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes,
+ UsedAssumedInformation))
return indicatePessimisticFixpoint();
return ChangeStatus::UNCHANGED;
// Discover returned values from all live returned instructions in the
// associated function.
- if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret}))
+ bool UsedAssumedInformation = false;
+ if (!A.checkForAllInstructions(ReturnInstCB, *this, {Instruction::Ret},
+ UsedAssumedInformation))
return indicatePessimisticFixpoint();
return Changed;
}
return !cast<CallBase>(I).isConvergent();
};
- if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this) ||
- !A.checkForAllCallLikeInstructions(CheckForNoSync, *this))
+ bool UsedAssumedInformation = false;
+ if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this,
+ UsedAssumedInformation) ||
+ !A.checkForAllCallLikeInstructions(CheckForNoSync, *this,
+ UsedAssumedInformation))
return indicatePessimisticFixpoint();
return ChangeStatus::UNCHANGED;
return NoFreeAA.isAssumedNoFree();
};
- if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this))
+ bool UsedAssumedInformation = false;
+ if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this,
+ UsedAssumedInformation))
return indicatePessimisticFixpoint();
return ChangeStatus::UNCHANGED;
}
return true;
};
- if (!A.checkForAllCallLikeInstructions(CheckForNoRecurse, *this))
+ bool UsedAssumedInformation = false;
+ if (!A.checkForAllCallLikeInstructions(CheckForNoRecurse, *this,
+ UsedAssumedInformation))
return indicatePessimisticFixpoint();
return ChangeStatus::UNCHANGED;
}
return true;
};
+ bool UsedAssumedInformation = false;
A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
{Instruction::Load, Instruction::Store,
Instruction::AtomicCmpXchg,
Instruction::AtomicRMW},
+ UsedAssumedInformation,
/* CheckBBLivenessOnly */ true);
A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br},
+ UsedAssumedInformation,
/* CheckBBLivenessOnly */ true);
- A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this);
+ A.checkForAllCallLikeInstructions(InspectCallSiteForUB, *this,
+ UsedAssumedInformation);
// If the returned position of the anchor scope has noundef attriubte, check
// all returned instructions.
if (!getAnchorScope()->getReturnType()->isVoidTy()) {
const IRPosition &ReturnIRP = IRPosition::returned(*getAnchorScope());
- if (!A.isAssumedDead(ReturnIRP, this, nullptr)) {
+ if (!A.isAssumedDead(ReturnIRP, this, nullptr, UsedAssumedInformation)) {
auto &RetPosNoUndefAA =
A.getAAFor<AANoUndef>(*this, ReturnIRP, DepClassTy::NONE);
if (RetPosNoUndefAA.isKnownNoUndef())
return NoRecurseAA.isAssumedNoRecurse();
};
- if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this))
+ bool UsedAssumedInformation = false;
+ if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this,
+ UsedAssumedInformation))
return indicatePessimisticFixpoint();
return ChangeStatus::UNCHANGED;
/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A) override {
+ bool UsedAssumedInformation = false;
A.checkForAllInstructions([](Instruction &) { return true; }, *this,
- {Instruction::Ret});
+ {Instruction::Ret}, UsedAssumedInformation);
auto PredForCallSite = [&](AbstractCallSite ACS) {
if (ACS.isCallbackCall() || !ACS.getInstruction())
AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
return true;
};
- A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret});
+ bool UsedAssumedInformation = false;
+ A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret},
+ UsedAssumedInformation);
return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
}
/// See AbstractAttribute::updateImpl(Attributor &A).
virtual ChangeStatus updateImpl(Attributor &A) override {
auto CheckForNoReturn = [](Instruction &) { return false; };
+ bool UsedAssumedInformation = false;
if (!A.checkForAllInstructions(CheckForNoReturn, *this,
- {(unsigned)Instruction::Ret}))
+ {(unsigned)Instruction::Ret},
+ UsedAssumedInformation))
return indicatePessimisticFixpoint();
return ChangeStatus::UNCHANGED;
}
/// See CaptureTracker::shouldExplore(...).
bool shouldExplore(const Use *U) override {
// Check liveness and ignore droppable users.
+ bool UsedAssumedInformation = false;
return !U->getUser()->isDroppable() &&
- !A.isAssumedDead(*U, &NoCaptureAA, &IsDeadAA);
+ !A.isAssumedDead(*U, &NoCaptureAA, &IsDeadAA,
+ UsedAssumedInformation);
}
/// Update the state according to \p CapturedInMem, \p CapturedInInt, and
// in other functions, e.g., we don't want to say a an argument in a
// static function is actually an argument in a different function.
Value &ArgOp = ACSArgPos.getAssociatedValue();
- bool UsedAssumedInformation;
+ bool UsedAssumedInformation = false;
Optional<Value *> SimpleArgOp =
A.getAssumedSimplified(ACSArgPos, *this, UsedAssumedInformation);
if (!SimpleArgOp.hasValue())
DepClassTy::REQUIRED);
auto PredForReturned =
[&](Value &RetVal, const SmallSetVector<ReturnInst *, 4> &RetInsts) {
- bool UsedAssumedInformation;
+ bool UsedAssumedInformation = false;
Optional<Value *> CSRetVal = A.translateArgumentToCallSiteContent(
&RetVal, *cast<CallBase>(getCtxI()), *this,
UsedAssumedInformation);
return true;
};
+ bool UsedAssumedInformation = false;
bool Success = A.checkForAllCallLikeInstructions(
- AllocationIdentifierCB, *this, /* CheckBBLivenessOnly */ false,
+ AllocationIdentifierCB, *this, UsedAssumedInformation,
+ /* CheckBBLivenessOnly */ false,
/* CheckPotentiallyDead */ true);
(void)Success;
assert(Success && "Did not expect the call base visit callback to fail!");
continue;
// No need to analyze dead calls, ignore them instead.
- if (A.isAssumedDead(*DI.CB, this, &LivenessAA,
+ bool UsedAssumedInformation = false;
+ if (A.isAssumedDead(*DI.CB, this, &LivenessAA, UsedAssumedInformation,
/* CheckBBLivenessOnly */ true))
continue;
// escape into tail recursion.
// TODO: Be smarter about new allocas escaping into tail calls.
SmallVector<CallInst *, 16> TailCalls;
+ bool UsedAssumedInformation = false;
if (!A.checkForAllInstructions(
[&](Instruction &I) {
CallInst &CI = cast<CallInst>(I);
TailCalls.push_back(&CI);
return true;
},
- *this, {Instruction::Call}))
+ *this, {Instruction::Call}, UsedAssumedInformation))
return ChangeStatus::UNCHANGED;
Argument *Arg = getAssociatedArgument();
return !isAtFixpoint();
};
- if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
+ bool UsedAssumedInformation = false;
+ if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
+ UsedAssumedInformation))
return indicatePessimisticFixpoint();
return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
for (unsigned i = 0; i < Uses.size() && !isAtFixpoint(); i++) {
const Use *U = Uses[i];
Instruction *UserI = cast<Instruction>(U->getUser());
+ bool UsedAssumedInformation = false;
LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << **U << " in " << *UserI
- << " [Dead: " << (A.isAssumedDead(*U, this, &LivenessAA))
+ << " [Dead: "
+ << (A.isAssumedDead(*U, this, &LivenessAA,
+ UsedAssumedInformation))
<< "]\n");
- if (A.isAssumedDead(*U, this, &LivenessAA))
+ if (A.isAssumedDead(*U, this, &LivenessAA, UsedAssumedInformation))
continue;
// Droppable users, e.g., llvm::assume does not actually perform any action.
return getAssumedNotAccessedLocation() != VALID_STATE;
};
- if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
+ bool UsedAssumedInformation = false;
+ if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this,
+ UsedAssumedInformation))
return indicatePessimisticFixpoint();
Changed |= AssumedState != getAssumed();
const DominatorTree *DT =
InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(
*I->getFunction());
- return DT && DT->dominates(I, CtxI);
+ return DT && DT->dominates(I, CtxI);
}
return true;
// We don't manifest noundef attribute for dead positions because the
// associated values with dead positions would be replaced with undef
// values.
- if (A.isAssumedDead(getIRPosition(), nullptr, nullptr))
+ bool UsedAssumedInformation = false;
+ if (A.isAssumedDead(getIRPosition(), nullptr, nullptr,
+ UsedAssumedInformation))
return ChangeStatus::UNCHANGED;
// A position whose simplified value does not have any value is
// considered to be dead. We don't manifest noundef in such positions for
// the same reason above.
- bool UsedAssumedInformation = false;
if (!A.getAssumedSimplified(getIRPosition(), *this, UsedAssumedInformation)
.hasValue())
return ChangeStatus::UNCHANGED;
};
// Visit all callable instructions.
- if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this))
+ bool UsedAssumedInformation = false;
+ if (!A.checkForAllCallLikeInstructions(ProcessCallInst, *this,
+ UsedAssumedInformation))
// If we haven't looked at all call like instructions, assume that there
// are unknown callees.
HasUnknownCallee = true;
// Track all changes of an ICV.
SetterRFI.foreachUse(TrackValues, F);
+ bool UsedAssumedInformation = false;
A.checkForAllInstructions(CallCheck, *this, {Instruction::Call},
+ UsedAssumedInformation,
/* CheckBBLivenessOnly */ true);
/// TODO: Figure out a way to avoid adding entry in
return true;
};
+ bool UsedAssumedInformation = false;
if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret},
+ UsedAssumedInformation,
/* CheckBBLivenessOnly */ true))
UniqueICVValue = nullptr;
SPMDCompatibilityTracker.insert(&I);
return true;
};
- if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
+
+ bool UsedAssumedInformationInCheckRWInst = false;
+ if (!A.checkForAllReadWriteInstructions(
+ CheckRWInst, *this, UsedAssumedInformationInCheckRWInst))
SPMDCompatibilityTracker.indicatePessimisticFixpoint();
// Callback to check a call instruction.
return true;
};
- if (!A.checkForAllCallLikeInstructions(CheckCallInst, *this))
+ bool UsedAssumedInformationInCheckCallInst = false;
+ if (!A.checkForAllCallLikeInstructions(
+ CheckCallInst, *this, UsedAssumedInformationInCheckCallInst))
return indicatePessimisticFixpoint();
return StateBefore == getState() ? ChangeStatus::UNCHANGED