29#define DEBUG_TYPE "predicateinfo"
35 cl::desc(
"Verify PredicateInfo in legacy printer pass."));
37 "Controls which variables are renamed with predicateinfo");
48 "Only branches and switches should have PHIOnly defs that "
49 "require branch blocks.");
57 "Not a predicate info type we know how to get a terminator from.");
63std::pair<BasicBlock *, BasicBlock *> getBlockEdge(
const PredicateBase *
PB) {
65 "Not a predicate info type we know how to get an edge from.");
67 return std::make_pair(PEdge->From, PEdge->To);
104 if (
A.DFSIn !=
B.DFSIn)
105 return A.DFSIn <
B.DFSIn;
107 "Equal DFS-in numbers imply equal out numbers");
110 if (
A.LocalNum !=
B.LocalNum)
111 return A.LocalNum <
B.LocalNum;
127 assert(
A.PInfo &&
B.PInfo &&
"Must be predicate info def");
135 return std::make_pair(
PHI->getIncomingBlock(*VD.
U),
PHI->getParent());
138 return ::getBlockEdge(VD.
PInfo);
152 "DFS numbers for A should match the ones of the source block");
154 "DFS numbers for B should match the ones of the source block");
155 assert(
A.DFSIn ==
B.DFSIn &&
"Values must be in the same block");
168 assert((!
A.PInfo || !
A.U) && (!
B.PInfo || !
B.U) &&
169 "Def and U cannot be set at the same time");
171 return std::tie(AIn, isAUse) < std::tie(BIn, isBUse);
180 assert(VD.
PInfo &&
"No use, and no predicateinfo should not occur");
182 "Middle of block should only occur for assumes");
218 ValueInfo &getOrCreateValueInfo(
Value *);
219 const ValueInfo &getValueInfo(
Value *)
const;
233 Value *Def =
nullptr;
235 StackEntry(
const ValueDFS *V) : V(V) {}
240 Value *materializeStack(
unsigned int &, ValueDFSStack &,
Value *);
241 bool stackIsInScope(
const ValueDFSStack &,
const ValueDFS &)
const;
242 void popStackUntilDFSScope(ValueDFSStack &,
const ValueDFS &);
247 : PI(PI), F(F), DT(DT), AC(AC), Allocator(Allocator) {
249 ValueInfos.resize(1);
255bool PredicateInfoBuilder::stackIsInScope(
const ValueDFSStack &Stack,
257 assert(!Stack.empty() &&
"Should not be called with empty stack");
263 const ValueDFS &Top = *Stack.back().V;
264 assert(Top.
PInfo &&
"RenameStack should only contain predicate infos (defs)");
267 assert(VDUse.
PInfo &&
"A non-use VDUse should have a predicate info");
272 getBlockEdge(Top.
PInfo) == getBlockEdge(VDUse.
PInfo);
279 if (EdgePred != getBranchBlock(Top.
PInfo))
283 return DT.dominates(getBlockEdge(Top.
PInfo), *VDUse.
U);
289void PredicateInfoBuilder::popStackUntilDFSScope(ValueDFSStack &Stack,
291 while (!
Stack.empty() && !stackIsInScope(Stack, VD))
297void PredicateInfoBuilder::convertUsesToDFSOrdered(
299 for (
auto &U :
Op->uses()) {
303 if (
I->isLifetimeStartOrEnd())
310 IBlock = PN->getIncomingBlock(U);
342 auto *Op0 = Comparison->getOperand(0);
343 auto *Op1 = Comparison->getOperand(1);
354 auto &OperandInfo = getOrCreateValueInfo(
Op);
355 if (OperandInfo.Infos.empty())
357 OperandInfo.Infos.push_back(
PB);
362void PredicateInfoBuilder::processAssume(
365 if (
II->hasOperandBundles()) {
366 for (
auto BOI :
II->bundle_op_infos()) {
368 if (RK.AttrKind == Attribute::NonNull)
369 addInfoFor(OpsToRename, RK.WasOn,
370 new (Allocator) PredicateBundleAssume(RK.WasOn,
II,
371 Attribute::NonNull));
377 SmallVector<Value *, 4> Worklist;
378 SmallPtrSet<Value *, 4> Visited;
380 while (!Worklist.
empty()) {
393 SmallVector<Value *, 4> Values;
400 for (
Value *V : Values) {
402 auto *PA =
new (Allocator) PredicateConditionAssume(V,
II,
Cond);
403 addInfoFor(OpsToRename, V, PA);
411void PredicateInfoBuilder::processBranch(
417 for (BasicBlock *Succ : {FirstBB, SecondBB}) {
418 bool TakenEdge = Succ == FirstBB;
421 if (Succ == BranchBB)
424 SmallVector<Value *, 4> Worklist;
425 SmallPtrSet<Value *, 4> Visited;
427 while (!Worklist.
empty()) {
441 SmallVector<Value *, 4> Values;
448 for (
Value *V : Values) {
450 PredicateBase *
PB =
new (Allocator)
451 PredicateBranch(V, BranchBB, Succ,
Cond, TakenEdge);
452 addInfoFor(OpsToRename, V,
PB);
460void PredicateInfoBuilder::processSwitch(
468 SmallDenseMap<BasicBlock *, unsigned, 16> SwitchEdges;
469 for (BasicBlock *TargetBlock :
successors(BranchBB))
470 ++SwitchEdges[TargetBlock];
473 for (
auto C :
SI->cases()) {
475 if (SwitchEdges.
lookup(TargetBlock) == 1) {
476 PredicateSwitch *PS =
new (Allocator) PredicateSwitch(
477 Op,
SI->getParent(), TargetBlock,
C.getCaseValue(), SI);
478 addInfoFor(OpsToRename,
Op, PS);
485 DT.updateDFSNumbers();
490 if (!DT.isReachableFromEntry(&BB))
499 processBranch(BI, &BB, OpsToRename);
501 processSwitch(
SI, &BB, OpsToRename);
504 for (
auto &Assume : AC.assumptions()) {
506 if (DT.isReachableFromEntry(
II->getParent()))
507 processAssume(
II,
II->getParent(), OpsToRename);
510 renameUses(OpsToRename);
515Value *PredicateInfoBuilder::materializeStack(
unsigned int &Counter,
516 ValueDFSStack &RenameStack,
519 auto RevIter = RenameStack.rbegin();
520 for (; RevIter != RenameStack.rend(); ++RevIter)
524 size_t Start = RevIter - RenameStack.rbegin();
528 for (
auto RenameIter = RenameStack.end() - Start;
529 RenameIter != RenameStack.end(); ++RenameIter) {
531 RenameIter == RenameStack.begin() ? OrigOp : (RenameIter - 1)->Def;
532 StackEntry &Result = *RenameIter;
533 auto *ValInfo = Result.V->PInfo;
534 ValInfo->RenamedOp = (RenameStack.end() - Start) == RenameStack.begin()
536 : (RenameStack.end() - Start - 1)->Def;
538 const Twine &Name =
"") {
549 Op->getName() +
"." +
Twine(Counter++));
550 PI.PredicateMap.insert({
PIC, ValInfo});
555 "Should not have gotten here without it being an assume");
558 BitCastInst *
PIC = CreateSSACopy(PAssume->AssumeInst->getNextNode(),
Op);
559 PI.PredicateMap.insert({
PIC, ValInfo});
563 return RenameStack.back().Def;
588 for (
auto *
Op : OpsToRename) {
590 unsigned Counter = 0;
592 const auto &ValueInfo = getValueInfo(
Op);
596 for (
const auto &PossibleCopy : ValueInfo.Infos) {
605 DomTreeNode *DomNode = DT.getNode(PAssume->AssumeInst->getParent());
610 VD.
PInfo = PossibleCopy;
616 auto BlockEdge = getBlockEdge(PossibleCopy);
617 if (!BlockEdge.second->getSinglePredecessor()) {
619 auto *DomNode = DT.getNode(BlockEdge.first);
623 VD.
PInfo = PossibleCopy;
631 auto *DomNode = DT.getNode(BlockEdge.second);
635 VD.
PInfo = PossibleCopy;
642 convertUsesToDFSOrdered(
Op, OrderedUses);
652 for (
const ValueDFS &VD : OrderedUses) {
655 if (RenameStack.
empty()) {
659 << RenameStack.
back().V->DFSIn <<
","
660 << RenameStack.
back().V->DFSOut <<
")\n");
667 popStackUntilDFSScope(RenameStack, VD);
676 if (RenameStack.
empty())
679 LLVM_DEBUG(
dbgs() <<
"Skipping execution due to debug counter\n");
688 Result.Def = materializeStack(Counter, RenameStack,
Op);
691 << *VD.
U->get() <<
" in " << *(VD.
U->getUser())
694 "Predicateinfo def should have dominated this use");
700PredicateInfoBuilder::ValueInfo &
701PredicateInfoBuilder::getOrCreateValueInfo(
Value *Operand) {
702 auto Res = ValueInfoNums.try_emplace(Operand, ValueInfos.size());
705 ValueInfos.resize(ValueInfos.size() + 1);
707 return ValueInfos[Res.first->second];
710const PredicateInfoBuilder::ValueInfo &
711PredicateInfoBuilder::getValueInfo(
Value *Operand)
const {
712 auto OINI = ValueInfoNums.lookup(Operand);
713 assert(OINI != 0 &&
"Operand was not really in the Value Info Numbers");
714 assert(OINI < ValueInfos.size() &&
715 "Value Info Number greater than size of Value Info Table");
716 return ValueInfos[OINI];
723 Builder.buildPredicateInfo();
730 "Cannot handle anything other than NonNull");
737 bool TrueEdge =
true;
739 TrueEdge = PBranch->TrueEdge;
761 Pred = Cmp->getPredicate();
762 OtherOp = Cmp->getOperand(1);
763 }
else if (Cmp->getOperand(1) ==
RenamedOp) {
764 Pred = Cmp->getSwappedPredicate();
765 OtherOp = Cmp->getOperand(0);
775 return {{Pred, OtherOp}};
793 const auto *PI = PredInfo.getPredicateInfoFor(&Inst);
798 Inst.getType() == Inst.getOperand(0)->getType());
799 Inst.replaceAllUsesWith(Inst.getOperand(0));
800 Inst.eraseFromParent();
808 OS <<
"PredicateInfo for function: " <<
F.getName() <<
"\n";
810 auto PredInfo = std::make_unique<PredicateInfo>(
F, DT, AC, Allocator);
831 if (
const auto *PI = PredInfo->getPredicateInfoFor(
I)) {
833 OS <<
"; branch predicate info { TrueEdge: " <<
PB->TrueEdge
834 <<
" Comparison:" << *
PB->Condition <<
" Edge: [";
835 PB->From->printAsOperand(OS);
837 PB->To->printAsOperand(OS);
840 OS <<
"; switch predicate info { CaseValue: " << *PS->CaseValue
842 PS->From->printAsOperand(OS);
844 PS->To->printAsOperand(OS);
847 OS <<
"; assume predicate info {";
852 OS <<
" Comparison:" << *PA->Condition;
855 OS <<
", RenamedOp: ";
856 PI->RenamedOp->printAsOperand(OS,
false);
864 F.print(OS, &Writer);
869 F.print(
dbgs(), &Writer);
877 std::make_unique<PredicateInfo>(
F, DT, AC, Allocator)->verifyPredicateInfo();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file defines the DenseMap class.
uint64_t IntrinsicInst * II
PassInstrumentationCallbacks PIC
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
static cl::opt< bool > VerifyPredicateInfo("verify-predicateinfo", cl::init(false), cl::Hidden, cl::desc("Verify PredicateInfo in legacy printer pass."))
static const unsigned MaxCondsPerBranch
This file implements the PredicateInfo analysis, which creates an Extended SSA form for operations us...
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallPtrSet class.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This represents the llvm.assume intrinsic.
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
static LLVM_ABI StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind)
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
This class represents a no-op cast from one type to another.
Conditional or Unconditional Branch instruction.
bool isConditional() const
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
static bool shouldExecute(CounterInfo &Counter)
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
unsigned getDFSNumIn() const
getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes in the dominator tree.
unsigned getDFSNumOut() const
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
LLVM_ABI std::optional< PredicateConstraint > getConstraint() const
Fetch condition in the form of PredicateConstraint, if possible.
PredicateInfoAnnotatedWriter(const PredicateInfo *M)
void emitInstructionAnnot(const Instruction *I, formatted_raw_ostream &OS) override
emitInstructionAnnot - This may be implemented to emit a string right before an instruction is emitte...
friend class PredicateInfo
void emitBasicBlockStartAnnot(const BasicBlock *BB, formatted_raw_ostream &OS) override
emitBasicBlockStartAnnot - This may be implemented to emit a string right after the basic block label...
PredicateInfoBuilder(PredicateInfo &PI, Function &F, DominatorTree &DT, AssumptionCache &AC, BumpPtrAllocator &Allocator)
void buildPredicateInfo()
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Encapsulates PredicateInfo, including all data associated with memory accesses.
friend class PredicateInfoAnnotatedWriter
LLVM_ABI void verifyPredicateInfo() const
friend class PredicateInfoBuilder
LLVM_ABI void print(raw_ostream &) const
LLVM_ABI PredicateInfo(Function &, DominatorTree &, AssumptionCache &, BumpPtrAllocator &)
LLVM_ABI void dump() const
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
NoWrapTrunc_match< OpTy, TruncInst::NoUnsignedWrap > m_NUWTrunc(const OpTy &Op)
Matches trunc nuw.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
void stable_sort(R &&Range)
void collectCmpOps(CmpInst *Comparison, SmallVectorImpl< Value * > &CmpOperands)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto successors(const MachineBasicBlock *BB)
static void replaceCreatedSSACopys(PredicateInfo &PredInfo, Function &F)
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
auto cast_or_null(const Y &Val)
bool shouldRename(Value *V)
DomTreeNodeBase< BasicBlock > DomTreeNode
LLVM_ABI RetainedKnowledge getKnowledgeFromBundle(AssumeInst &Assume, const CallBase::BundleOpInfo &BOI)
This extracts the Knowledge from an element of an operand bundle.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
std::pair< BasicBlock *, BasicBlock * > getBlockEdge(const ValueDFS &VD) const
bool operator()(const ValueDFS &A, const ValueDFS &B) const
const Instruction * getDefOrUser(const ValueDFS &VD) const
bool comparePHIRelated(const ValueDFS &A, const ValueDFS &B) const
ValueDFS_Compare(DominatorTree &DT)
bool localComesBefore(const ValueDFS &A, const ValueDFS &B) const