[PATCH] D16622: Value: Provide a shortcut in stripPointerCastsAndOffsets()

Matthias Braun via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 26 20:15:23 PST 2016


MatzeB created this revision.
MatzeB added reviewers: chandlerc, sunfish, baldrick.
MatzeB added a subscriber: llvm-commits.
MatzeB set the repository for this revision to rL LLVM.
Herald added a subscriber: mcrosier.

The majority of stripPointerCastsAndOffsets() queries can be resolved
after checking 1 or 2 values. This patch delays the creation and
insertion into a SmallPtrSet until we have to check more than that. This
slightly improves compile time in my benchmarks.

Repository:
  rL LLVM

http://reviews.llvm.org/D16622

Files:
  lib/IR/Value.cpp

Index: lib/IR/Value.cpp
===================================================================
--- lib/IR/Value.cpp
+++ lib/IR/Value.cpp
@@ -421,43 +421,59 @@
 };
 
 template <PointerStripKind StripKind>
+static Value *stripOne(Value *V) {
+  if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
+    switch (StripKind) {
+    case PSK_ZeroIndicesAndAliases:
+    case PSK_ZeroIndices:
+      if (!GEP->hasAllZeroIndices())
+        return nullptr;
+      break;
+    case PSK_InBoundsConstantIndices:
+      if (!GEP->hasAllConstantIndices())
+        return nullptr;
+      // fallthrough
+    case PSK_InBounds:
+      if (!GEP->isInBounds())
+        return nullptr;
+      break;
+    }
+    return GEP->getPointerOperand();
+  } else if (Operator::getOpcode(V) == Instruction::BitCast ||
+             Operator::getOpcode(V) == Instruction::AddrSpaceCast) {
+    return cast<Operator>(V)->getOperand(0);
+  } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) {
+    if (StripKind == PSK_ZeroIndices || GA->mayBeOverridden())
+      return nullptr;
+    return GA->getAliasee();
+  } else {
+    return nullptr;
+  }
+}
+
+template <PointerStripKind StripKind>
 static Value *stripPointerCastsAndOffsets(Value *V) {
   if (!V->getType()->isPointerTy())
     return V;
 
+  // This function is performance sensitive so try the common case first
+  // before constructing the SmallPtrSet.
+  Value *Next = stripOne<StripKind>(V);
+  if (Next == nullptr)
+    return V;
+
   // Even though we don't look through PHI nodes, we could be called on an
   // instruction in an unreachable block, which may be on a cycle.
   SmallPtrSet<Value *, 4> Visited;
-
   Visited.insert(V);
+  if (!Visited.insert(Next).second)
+    return Next;
+  V = Next;
   do {
-    if (GEPOperator *GEP = dyn_cast<GEPOperator>(V)) {
-      switch (StripKind) {
-      case PSK_ZeroIndicesAndAliases:
-      case PSK_ZeroIndices:
-        if (!GEP->hasAllZeroIndices())
-          return V;
-        break;
-      case PSK_InBoundsConstantIndices:
-        if (!GEP->hasAllConstantIndices())
-          return V;
-        // fallthrough
-      case PSK_InBounds:
-        if (!GEP->isInBounds())
-          return V;
-        break;
-      }
-      V = GEP->getPointerOperand();
-    } else if (Operator::getOpcode(V) == Instruction::BitCast ||
-               Operator::getOpcode(V) == Instruction::AddrSpaceCast) {
-      V = cast<Operator>(V)->getOperand(0);
-    } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) {
-      if (StripKind == PSK_ZeroIndices || GA->mayBeOverridden())
-        return V;
-      V = GA->getAliasee();
-    } else {
+    Next = stripOne<StripKind>(V);
+    if (Next == nullptr)
       return V;
-    }
+    V = Next;
     assert(V->getType()->isPointerTy() && "Unexpected operand type!");
   } while (Visited.insert(V).second);
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D16622.46096.patch
Type: text/x-patch
Size: 2840 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160127/8f1d8429/attachment.bin>


More information about the llvm-commits mailing list