diff options
Diffstat (limited to 'llvm/lib/Analysis/CFLAliasAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/CFLAliasAnalysis.cpp | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/llvm/lib/Analysis/CFLAliasAnalysis.cpp b/llvm/lib/Analysis/CFLAliasAnalysis.cpp index 84b31dff055..c262b9ea2ad 100644 --- a/llvm/lib/Analysis/CFLAliasAnalysis.cpp +++ b/llvm/lib/Analysis/CFLAliasAnalysis.cpp @@ -539,6 +539,19 @@ public: Output.push_back(Edge(&Inst, From1, EdgeType::Assign, AttrNone)); Output.push_back(Edge(&Inst, From2, EdgeType::Assign, AttrNone)); } + + void visitConstantExpr(ConstantExpr *CE) { + switch (CE->getOpcode()) { + default: + llvm_unreachable("Unknown instruction type encountered!"); +// Build the switch statement using the Instruction.def file. +#define HANDLE_INST(NUM, OPCODE, CLASS) \ + case Instruction::OPCODE: \ + visit##OPCODE(*(CLASS *)CE); \ + break; +#include "llvm/IR/Instruction.def" + } + } }; // For a given instruction, we need to know which Value* to get the @@ -741,6 +754,10 @@ static EdgeType flipWeight(EdgeType); static void argsToEdges(CFLAliasAnalysis &, Instruction *, SmallVectorImpl<Edge> &); +// Gets edges of the given ConstantExpr*, writing them to the SmallVector*. +static void argsToEdges(CFLAliasAnalysis &, ConstantExpr *, + SmallVectorImpl<Edge> &); + // Gets the "Level" that one should travel in StratifiedSets // given an EdgeType. static Level directionOfEdgeType(EdgeType); @@ -807,6 +824,13 @@ static bool hasUsefulEdges(Instruction *Inst) { return !isa<CmpInst>(Inst) && !isa<FenceInst>(Inst) && !IsNonInvokeTerminator; } +static bool hasUsefulEdges(ConstantExpr *CE) { + // ConstantExpr doens't have terminators, invokes, or fences, so only needs + // to check for compares. + return CE->getOpcode() != Instruction::ICmp && + CE->getOpcode() != Instruction::FCmp; +} + static Optional<StratifiedAttr> valueToAttrIndex(Value *Val) { if (isa<GlobalValue>(Val)) return AttrGlobalIndex; @@ -846,6 +870,13 @@ static void argsToEdges(CFLAliasAnalysis &Analysis, Instruction *Inst, v.visit(Inst); } +static void argsToEdges(CFLAliasAnalysis &Analysis, ConstantExpr *CE, + SmallVectorImpl<Edge> &Output) { + assert(hasUsefulEdges(CE) && "Expected constant expr to have 'useful' edges"); + GetEdgesVisitor v(Analysis, Output); + v.visitConstantExpr(CE); +} + static Level directionOfEdgeType(EdgeType Weight) { switch (Weight) { case EdgeType::Reference: @@ -865,25 +896,23 @@ static void constexprToEdges(CFLAliasAnalysis &Analysis, Worklist.push_back(&CExprToCollapse); SmallVector<Edge, 8> ConstexprEdges; + SmallPtrSet<ConstantExpr *, 4> Visited; while (!Worklist.empty()) { auto *CExpr = Worklist.pop_back_val(); - std::unique_ptr<Instruction> Inst(CExpr->getAsInstruction()); - if (!hasUsefulEdges(Inst.get())) + if (!hasUsefulEdges(CExpr)) continue; ConstexprEdges.clear(); - argsToEdges(Analysis, Inst.get(), ConstexprEdges); + argsToEdges(Analysis, CExpr, ConstexprEdges); for (auto &Edge : ConstexprEdges) { - if (Edge.From == Inst.get()) - Edge.From = CExpr; - else if (auto *Nested = dyn_cast<ConstantExpr>(Edge.From)) - Worklist.push_back(Nested); - - if (Edge.To == Inst.get()) - Edge.To = CExpr; - else if (auto *Nested = dyn_cast<ConstantExpr>(Edge.To)) - Worklist.push_back(Nested); + if (auto *Nested = dyn_cast<ConstantExpr>(Edge.From)) + if (Visited.insert(Nested).second) + Worklist.push_back(Nested); + + if (auto *Nested = dyn_cast<ConstantExpr>(Edge.To)) + if (Visited.insert(Nested).second) + Worklist.push_back(Nested); } Results.append(ConstexprEdges.begin(), ConstexprEdges.end()); |