30#define DEBUG_TYPE "predicateinfo"
36 cl::desc(
"Verify PredicateInfo in legacy printer pass."));
38 "Controls which variables are renamed with predicateinfo");
49 "Only branches and switches should have PHIOnly defs that "
50 "require branch blocks.");
58 "Not a predicate info type we know how to get a terminator from.");
64std::pair<BasicBlock *, BasicBlock *> getBlockEdge(
const PredicateBase *
PB) {
66 "Not a predicate info type we know how to get an edge from.");
68 return std::make_pair(PEdge->From, PEdge->To);
105 if (
A.DFSIn !=
B.DFSIn)
106 return A.DFSIn <
B.DFSIn;
108 "Equal DFS-in numbers imply equal out numbers");
111 if (
A.LocalNum !=
B.LocalNum)
112 return A.LocalNum <
B.LocalNum;
128 assert(
A.PInfo &&
B.PInfo &&
"Must be predicate info def");
136 return std::make_pair(
PHI->getIncomingBlock(*VD.
U),
PHI->getParent());
139 return ::getBlockEdge(VD.
PInfo);
153 "DFS numbers for A should match the ones of the source block");
155 "DFS numbers for B should match the ones of the source block");
156 assert(
A.DFSIn ==
B.DFSIn &&
"Values must be in the same block");
169 assert((!
A.PInfo || !
A.U) && (!
B.PInfo || !
B.U) &&
170 "Def and U cannot be set at the same time");
172 return std::tie(AIn, isAUse) < std::tie(BIn, isBUse);
181 assert(VD.
PInfo &&
"No use, and no predicateinfo should not occur");
183 "Middle of block should only occur for assumes");
219 ValueInfo &getOrCreateValueInfo(
Value *);
220 const ValueInfo &getValueInfo(
Value *)
const;
234 Value *Def =
nullptr;
236 StackEntry(
const ValueDFS *V) : V(V) {}
241 Value *materializeStack(
unsigned int &, ValueDFSStack &,
Value *);
242 bool stackIsInScope(
const ValueDFSStack &,
const ValueDFS &)
const;
243 void popStackUntilDFSScope(ValueDFSStack &,
const ValueDFS &);
248 : PI(PI), F(F), DT(DT), AC(AC), Allocator(Allocator) {
250 ValueInfos.resize(1);
256bool PredicateInfoBuilder::stackIsInScope(
const ValueDFSStack &Stack,
258 assert(!Stack.empty() &&
"Should not be called with empty stack");
264 const ValueDFS &Top = *Stack.back().V;
265 assert(Top.
PInfo &&
"RenameStack should only contain predicate infos (defs)");
268 assert(VDUse.
PInfo &&
"A non-use VDUse should have a predicate info");
273 getBlockEdge(Top.
PInfo) == getBlockEdge(VDUse.
PInfo);
280 if (EdgePred != getBranchBlock(Top.
PInfo))
284 return DT.dominates(getBlockEdge(Top.
PInfo), *VDUse.
U);
290void PredicateInfoBuilder::popStackUntilDFSScope(ValueDFSStack &Stack,
292 while (!
Stack.empty() && !stackIsInScope(Stack, VD))
298void PredicateInfoBuilder::convertUsesToDFSOrdered(
300 for (
auto &U :
Op->uses()) {
304 if (
I->isLifetimeStartOrEnd())
311 IBlock = PN->getIncomingBlock(U);
343 auto *Op0 = Comparison->getOperand(0);
344 auto *Op1 = Comparison->getOperand(1);
355 auto &OperandInfo = getOrCreateValueInfo(
Op);
356 if (OperandInfo.Infos.empty())
358 OperandInfo.Infos.push_back(
PB);
363void PredicateInfoBuilder::processAssume(
366 if (
II->hasOperandBundles()) {
367 for (
auto OBU :
II->operand_bundles()) {
370 addInfoFor(OpsToRename, Ptr,
372 PredicateBundleAssume(Ptr,
II, BundleAttr::NonNull));
378 SmallVector<Value *, 4> Worklist;
379 SmallPtrSet<Value *, 4> Visited;
381 while (!Worklist.
empty()) {
394 SmallVector<Value *, 4> Values;
401 for (
Value *V : Values) {
403 auto *PA =
new (Allocator) PredicateConditionAssume(V,
II,
Cond);
404 addInfoFor(OpsToRename, V, PA);
412void PredicateInfoBuilder::processBranch(
418 for (BasicBlock *Succ : {FirstBB, SecondBB}) {
419 bool TakenEdge = Succ == FirstBB;
422 if (Succ == BranchBB)
425 SmallVector<Value *, 4> Worklist;
426 SmallPtrSet<Value *, 4> Visited;
428 while (!Worklist.
empty()) {
442 SmallVector<Value *, 4> Values;
449 for (
Value *V : Values) {
451 PredicateBase *
PB =
new (Allocator)
452 PredicateBranch(V, BranchBB, Succ,
Cond, TakenEdge);
453 addInfoFor(OpsToRename, V,
PB);
461void PredicateInfoBuilder::processSwitch(
469 SmallDenseMap<BasicBlock *, unsigned, 16> SwitchEdges;
470 for (BasicBlock *TargetBlock :
successors(BranchBB))
471 ++SwitchEdges[TargetBlock];
474 for (
auto C :
SI->cases()) {
476 if (SwitchEdges.
lookup(TargetBlock) == 1) {
477 PredicateSwitch *PS =
new (Allocator) PredicateSwitch(
478 Op,
SI->getParent(), TargetBlock,
C.getCaseValue(), SI);
479 addInfoFor(OpsToRename,
Op, PS);
486 DT.updateDFSNumbers();
491 if (!DT.isReachableFromEntry(&BB))
498 processBranch(BI, &BB, OpsToRename);
500 processSwitch(
SI, &BB, OpsToRename);
503 for (
auto &Assume : AC.assumptions()) {
505 if (DT.isReachableFromEntry(
II->getParent()))
506 processAssume(
II,
II->getParent(), OpsToRename);
509 renameUses(OpsToRename);
514Value *PredicateInfoBuilder::materializeStack(
unsigned int &Counter,
515 ValueDFSStack &RenameStack,
518 auto RevIter = RenameStack.rbegin();
519 for (; RevIter != RenameStack.rend(); ++RevIter)
523 size_t Start = RevIter - RenameStack.rbegin();
527 for (
auto RenameIter = RenameStack.end() - Start;
528 RenameIter != RenameStack.end(); ++RenameIter) {
530 RenameIter == RenameStack.begin() ? OrigOp : (RenameIter - 1)->Def;
531 StackEntry &Result = *RenameIter;
532 auto *ValInfo = Result.V->PInfo;
533 ValInfo->RenamedOp = (RenameStack.end() - Start) == RenameStack.begin()
535 : (RenameStack.end() - Start - 1)->Def;
537 const Twine &Name =
"") {
548 Op->getName() +
"." +
Twine(Counter++));
549 PI.PredicateMap.insert({
PIC, ValInfo});
554 "Should not have gotten here without it being an assume");
557 BitCastInst *
PIC = CreateSSACopy(PAssume->AssumeInst->getNextNode(),
Op);
558 PI.PredicateMap.insert({
PIC, ValInfo});
562 return RenameStack.back().Def;
587 for (
auto *
Op : OpsToRename) {
589 unsigned Counter = 0;
591 const auto &ValueInfo = getValueInfo(
Op);
595 for (
const auto &PossibleCopy : ValueInfo.Infos) {
604 DomTreeNode *DomNode = DT.getNode(PAssume->AssumeInst->getParent());
609 VD.
PInfo = PossibleCopy;
615 auto BlockEdge = getBlockEdge(PossibleCopy);
616 if (!BlockEdge.second->getSinglePredecessor()) {
618 auto *DomNode = DT.getNode(BlockEdge.first);
622 VD.
PInfo = PossibleCopy;
630 auto *DomNode = DT.getNode(BlockEdge.second);
634 VD.
PInfo = PossibleCopy;
641 convertUsesToDFSOrdered(
Op, OrderedUses);
648 SmallVector<StackEntry, 8> RenameStack;
651 for (
const ValueDFS &VD : OrderedUses) {
654 if (RenameStack.
empty()) {
658 << RenameStack.
back().V->DFSIn <<
","
659 << RenameStack.
back().V->DFSOut <<
")\n");
666 popStackUntilDFSScope(RenameStack, VD);
675 if (RenameStack.
empty())
678 LLVM_DEBUG(
dbgs() <<
"Skipping execution due to debug counter\n");
687 Result.Def = materializeStack(Counter, RenameStack,
Op);
690 << *VD.
U->get() <<
" in " << *(VD.
U->getUser())
693 "Predicateinfo def should have dominated this use");
699PredicateInfoBuilder::ValueInfo &
700PredicateInfoBuilder::getOrCreateValueInfo(
Value *Operand) {
701 auto Res = ValueInfoNums.try_emplace(Operand, ValueInfos.size());
704 ValueInfos.resize(ValueInfos.size() + 1);
706 return ValueInfos[Res.first->second];
709const PredicateInfoBuilder::ValueInfo &
710PredicateInfoBuilder::getValueInfo(
Value *Operand)
const {
711 auto OINI = ValueInfoNums.lookup(Operand);
712 assert(OINI != 0 &&
"Operand was not really in the Value Info Numbers");
713 assert(OINI < ValueInfos.size() &&
714 "Value Info Number greater than size of Value Info Table");
715 return ValueInfos[OINI];
722 Builder.buildPredicateInfo();
729 "Cannot handle anything other than NonNull");
736 bool TrueEdge =
true;
738 TrueEdge = PBranch->TrueEdge;
760 Pred = Cmp->getPredicate();
761 OtherOp = Cmp->getOperand(1);
762 }
else if (Cmp->getOperand(1) ==
RenamedOp) {
763 Pred = Cmp->getSwappedPredicate();
764 OtherOp = Cmp->getOperand(0);
774 return {{Pred, OtherOp}};
792 const auto *PI = PredInfo.getPredicateInfoFor(&Inst);
797 Inst.getType() == Inst.getOperand(0)->getType());
798 Inst.replaceAllUsesWith(Inst.getOperand(0));
799 Inst.eraseFromParent();
807 OS <<
"PredicateInfo for function: " <<
F.getName() <<
"\n";
809 auto PredInfo = std::make_unique<PredicateInfo>(
F, DT, AC, Allocator);
830 if (
const auto *PI = PredInfo->getPredicateInfoFor(
I)) {
832 OS <<
"; branch predicate info { TrueEdge: " <<
PB->TrueEdge
833 <<
" Comparison:" << *
PB->Condition <<
" Edge: [";
834 PB->From->printAsOperand(OS);
836 PB->To->printAsOperand(OS);
839 OS <<
"; switch predicate info { CaseValue: " << *PS->CaseValue
841 PS->From->printAsOperand(OS);
843 PS->To->printAsOperand(OS);
846 OS <<
"; assume predicate info {";
851 OS <<
" Comparison:" << *PA->Condition;
854 OS <<
", RenamedOp: ";
855 PI->RenamedOp->printAsOperand(OS,
false);
863 F.print(OS, &Writer);
868 F.print(
dbgs(), &Writer);
876 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.
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.
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,...
Conditional Branch instruction.
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
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
Return the entry for the specified key, or a default constructed value if no such entry exists.
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_Value()
Match an arbitrary value and ignore it.
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.
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)
BundleAttr getBundleAttrFromOBU(OperandBundleUse OBU)
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 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...
LLVM_ABI AssumeNonNullInfo getAssumeNonNullInfo(OperandBundleUse)
DWARFExpression::Operation Op
LLVM_ABI StringRef getNameFromBundleAttr(BundleAttr)
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