123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- PredicateInfo.h - Build PredicateInfo ----------------------*-C++-*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- ///
- /// \file
- /// This file implements the PredicateInfo analysis, which creates an Extended
- /// SSA form for operations used in branch comparisons and llvm.assume
- /// comparisons.
- ///
- /// Copies of these operations are inserted into the true/false edge (and after
- /// assumes), and information attached to the copies. All uses of the original
- /// operation in blocks dominated by the true/false edge (and assume), are
- /// replaced with uses of the copies. This enables passes to easily and sparsely
- /// propagate condition based info into the operations that may be affected.
- ///
- /// Example:
- /// %cmp = icmp eq i32 %x, 50
- /// br i1 %cmp, label %true, label %false
- /// true:
- /// ret i32 %x
- /// false:
- /// ret i32 1
- ///
- /// will become
- ///
- /// %cmp = icmp eq i32, %x, 50
- /// br i1 %cmp, label %true, label %false
- /// true:
- /// %x.0 = call \@llvm.ssa_copy.i32(i32 %x)
- /// ret i32 %x.0
- /// false:
- /// ret i32 1
- ///
- /// Using getPredicateInfoFor on x.0 will give you the comparison it is
- /// dominated by (the icmp), and that you are located in the true edge of that
- /// comparison, which tells you x.0 is 50.
- ///
- /// In order to reduce the number of copies inserted, predicateinfo is only
- /// inserted where it would actually be live. This means if there are no uses of
- /// an operation dominated by the branch edges, or by an assume, the associated
- /// predicate info is never inserted.
- ///
- ///
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_TRANSFORMS_UTILS_PREDICATEINFO_H
- #define LLVM_TRANSFORMS_UTILS_PREDICATEINFO_H
- #include "llvm/ADT/DenseMap.h"
- #include "llvm/ADT/SmallSet.h"
- #include "llvm/ADT/ilist.h"
- #include "llvm/ADT/ilist_node.h"
- #include "llvm/IR/Instructions.h"
- #include "llvm/IR/PassManager.h"
- #include "llvm/IR/ValueHandle.h"
- #include "llvm/Pass.h"
- namespace llvm {
- class AssumptionCache;
- class DominatorTree;
- class Function;
- class Value;
- class IntrinsicInst;
- class raw_ostream;
- enum PredicateType { PT_Branch, PT_Assume, PT_Switch };
- /// Constraint for a predicate of the form "cmp Pred Op, OtherOp", where Op
- /// is the value the constraint applies to (the ssa.copy result).
- struct PredicateConstraint {
- CmpInst::Predicate Predicate;
- Value *OtherOp;
- };
- // Base class for all predicate information we provide.
- // All of our predicate information has at least a comparison.
- class PredicateBase : public ilist_node<PredicateBase> {
- public:
- PredicateType Type;
- // The original operand before we renamed it.
- // This can be use by passes, when destroying predicateinfo, to know
- // whether they can just drop the intrinsic, or have to merge metadata.
- Value *OriginalOp;
- // The renamed operand in the condition used for this predicate. For nested
- // predicates, this is different to OriginalOp which refers to the initial
- // operand.
- Value *RenamedOp;
- // The condition associated with this predicate.
- Value *Condition;
- PredicateBase(const PredicateBase &) = delete;
- PredicateBase &operator=(const PredicateBase &) = delete;
- PredicateBase() = delete;
- virtual ~PredicateBase() = default;
- static bool classof(const PredicateBase *PB) {
- return PB->Type == PT_Assume || PB->Type == PT_Branch ||
- PB->Type == PT_Switch;
- }
- /// Fetch condition in the form of PredicateConstraint, if possible.
- std::optional<PredicateConstraint> getConstraint() const;
- protected:
- PredicateBase(PredicateType PT, Value *Op, Value *Condition)
- : Type(PT), OriginalOp(Op), Condition(Condition) {}
- };
- // Provides predicate information for assumes. Since assumes are always true,
- // we simply provide the assume instruction, so you can tell your relative
- // position to it.
- class PredicateAssume : public PredicateBase {
- public:
- IntrinsicInst *AssumeInst;
- PredicateAssume(Value *Op, IntrinsicInst *AssumeInst, Value *Condition)
- : PredicateBase(PT_Assume, Op, Condition), AssumeInst(AssumeInst) {}
- PredicateAssume() = delete;
- static bool classof(const PredicateBase *PB) {
- return PB->Type == PT_Assume;
- }
- };
- // Mixin class for edge predicates. The FROM block is the block where the
- // predicate originates, and the TO block is the block where the predicate is
- // valid.
- class PredicateWithEdge : public PredicateBase {
- public:
- BasicBlock *From;
- BasicBlock *To;
- PredicateWithEdge() = delete;
- static bool classof(const PredicateBase *PB) {
- return PB->Type == PT_Branch || PB->Type == PT_Switch;
- }
- protected:
- PredicateWithEdge(PredicateType PType, Value *Op, BasicBlock *From,
- BasicBlock *To, Value *Cond)
- : PredicateBase(PType, Op, Cond), From(From), To(To) {}
- };
- // Provides predicate information for branches.
- class PredicateBranch : public PredicateWithEdge {
- public:
- // If true, SplitBB is the true successor, otherwise it's the false successor.
- bool TrueEdge;
- PredicateBranch(Value *Op, BasicBlock *BranchBB, BasicBlock *SplitBB,
- Value *Condition, bool TakenEdge)
- : PredicateWithEdge(PT_Branch, Op, BranchBB, SplitBB, Condition),
- TrueEdge(TakenEdge) {}
- PredicateBranch() = delete;
- static bool classof(const PredicateBase *PB) {
- return PB->Type == PT_Branch;
- }
- };
- class PredicateSwitch : public PredicateWithEdge {
- public:
- Value *CaseValue;
- // This is the switch instruction.
- SwitchInst *Switch;
- PredicateSwitch(Value *Op, BasicBlock *SwitchBB, BasicBlock *TargetBB,
- Value *CaseValue, SwitchInst *SI)
- : PredicateWithEdge(PT_Switch, Op, SwitchBB, TargetBB,
- SI->getCondition()),
- CaseValue(CaseValue), Switch(SI) {}
- PredicateSwitch() = delete;
- static bool classof(const PredicateBase *PB) {
- return PB->Type == PT_Switch;
- }
- };
- /// Encapsulates PredicateInfo, including all data associated with memory
- /// accesses.
- class PredicateInfo {
- public:
- PredicateInfo(Function &, DominatorTree &, AssumptionCache &);
- ~PredicateInfo();
- void verifyPredicateInfo() const;
- void dump() const;
- void print(raw_ostream &) const;
- const PredicateBase *getPredicateInfoFor(const Value *V) const {
- return PredicateMap.lookup(V);
- }
- protected:
- // Used by PredicateInfo annotater, dumpers, and wrapper pass.
- friend class PredicateInfoAnnotatedWriter;
- friend class PredicateInfoPrinterLegacyPass;
- friend class PredicateInfoBuilder;
- private:
- Function &F;
- // This owns the all the predicate infos in the function, placed or not.
- iplist<PredicateBase> AllInfos;
- // This maps from copy operands to Predicate Info. Note that it does not own
- // the Predicate Info, they belong to the ValueInfo structs in the ValueInfos
- // vector.
- DenseMap<const Value *, const PredicateBase *> PredicateMap;
- // The set of ssa_copy declarations we created with our custom mangling.
- SmallSet<AssertingVH<Function>, 20> CreatedDeclarations;
- };
- // This pass does eager building and then printing of PredicateInfo. It is used
- // by
- // the tests to be able to build, dump, and verify PredicateInfo.
- class PredicateInfoPrinterLegacyPass : public FunctionPass {
- public:
- PredicateInfoPrinterLegacyPass();
- static char ID;
- bool runOnFunction(Function &) override;
- void getAnalysisUsage(AnalysisUsage &AU) const override;
- };
- /// Printer pass for \c PredicateInfo.
- class PredicateInfoPrinterPass
- : public PassInfoMixin<PredicateInfoPrinterPass> {
- raw_ostream &OS;
- public:
- explicit PredicateInfoPrinterPass(raw_ostream &OS) : OS(OS) {}
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
- };
- /// Verifier pass for \c PredicateInfo.
- struct PredicateInfoVerifierPass : PassInfoMixin<PredicateInfoVerifierPass> {
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
- };
- } // end namespace llvm
- #endif // LLVM_TRANSFORMS_UTILS_PREDICATEINFO_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|