Don't create instructions from ConstantExpr's in CFLAliasAnalysis.
authorPete Cooper <peter_cooper@apple.com>
Fri, 12 Jun 2015 16:13:54 +0000 (16:13 +0000)
committerPete Cooper <peter_cooper@apple.com>
Fri, 12 Jun 2015 16:13:54 +0000 (16:13 +0000)
The CFLAA code currently calls ConstantExpr::getAsInstruction which creates an instruction from a constant expr.

We then pass that instruction to the InstVisitor to analyze it.

Its not necessary to create these instructions as we can just cast from Constant to Operator in the visitor.  This is how other InstVisitor’s such as SelectionDAGBuilder handle ConstantExpr.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239616 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/CFLAliasAnalysis.cpp

index 84b31dff055aed40bc3665cb28c284c0f97282a5..c262b9ea2adf971119e5d50ae46e93ce9b8d5852 100644 (file)
@@ -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());