[PATCH] Teach InlineCost about address spaces

Matt Arsenault Matthew.Arsenault at amd.com
Wed Jul 31 13:08:11 PDT 2013


Depends on

http://llvm-reviews.chandlerc.com/D1114
and
http://llvm-reviews.chandlerc.com/D1250

http://llvm-reviews.chandlerc.com/D1251

Files:
  lib/Analysis/IPA/InlineCost.cpp
  test/Transforms/Inline/ptr-diff.ll

Index: lib/Analysis/IPA/InlineCost.cpp
===================================================================
--- lib/Analysis/IPA/InlineCost.cpp
+++ lib/Analysis/IPA/InlineCost.cpp
@@ -250,7 +250,7 @@
   if (!TD)
     return false;
 
-  unsigned IntPtrWidth = TD->getPointerSizeInBits();
+  unsigned IntPtrWidth = TD->getPointerTypeSizeInBits(GEP.getType());
   assert(IntPtrWidth == Offset.getBitWidth());
 
   for (gep_type_iterator GTI = gep_type_begin(GEP), GTE = gep_type_end(GEP);
@@ -390,24 +390,27 @@
 }
 
 bool CallAnalyzer::visitPtrToInt(PtrToIntInst &I) {
+  Type *Ty = I.getType();
+  Value *Op = I.getOperand(0);
   // Propagate constants through ptrtoint.
-  Constant *COp = dyn_cast<Constant>(I.getOperand(0));
+  Constant *COp = dyn_cast<Constant>(Op);
   if (!COp)
-    COp = SimplifiedValues.lookup(I.getOperand(0));
+    COp = SimplifiedValues.lookup(Op);
   if (COp)
-    if (Constant *C = ConstantExpr::getPtrToInt(COp, I.getType())) {
+    if (Constant *C = ConstantExpr::getPtrToInt(COp, Ty)) {
       SimplifiedValues[&I] = C;
       return true;
     }
 
   // Track base/offset pairs when converted to a plain integer provided the
   // integer is large enough to represent the pointer.
-  unsigned IntegerSize = I.getType()->getScalarSizeInBits();
-  if (TD && IntegerSize == TD->getPointerSizeInBits()) {
-    std::pair<Value *, APInt> BaseAndOffset
-      = ConstantOffsetPtrs.lookup(I.getOperand(0));
-    if (BaseAndOffset.first)
+  unsigned IntegerSize = Ty->getScalarSizeInBits();
+  unsigned AS = Op->getType()->getPointerAddressSpace();
+  if (TD && IntegerSize == TD->getPointerSizeInBits(AS)) {
+    std::pair<Value *, APInt> BaseAndOffset = ConstantOffsetPtrs.lookup(Op);
+    if (BaseAndOffset.first) {
       ConstantOffsetPtrs[&I] = BaseAndOffset;
+    }
   }
 
   // This is really weird. Technically, ptrtoint will disable SROA. However,
@@ -419,7 +422,7 @@
   // disable SROA (ext) w/o some later use that we would see and disable.
   Value *SROAArg;
   DenseMap<Value *, int>::iterator CostIt;
-  if (lookupSROAArgAndCost(I.getOperand(0), SROAArg, CostIt))
+  if (lookupSROAArgAndCost(Op, SROAArg, CostIt))
     SROAArgValues[&I] = SROAArg;
 
   return TargetTransformInfo::TCC_Free == TTI.getUserCost(&I);
@@ -440,7 +443,7 @@
   // modifications provided the integer is not too large.
   Value *Op = I.getOperand(0);
   unsigned IntegerSize = Op->getType()->getScalarSizeInBits();
-  if (TD && IntegerSize == TD->getPointerSizeInBits()) {
+  if (TD && IntegerSize == TD->getPointerTypeSizeInBits(I.getType())) {
     std::pair<Value *, APInt> BaseAndOffset = ConstantOffsetPtrs.lookup(Op);
     if (BaseAndOffset.first)
       ConstantOffsetPtrs[&I] = BaseAndOffset;
@@ -861,7 +864,8 @@
   if (!TD || !V->getType()->isPointerTy())
     return 0;
 
-  unsigned IntPtrWidth = TD->getPointerSizeInBits();
+  unsigned AS = V->getType()->getPointerAddressSpace();
+  unsigned IntPtrWidth = TD->getPointerSizeInBits(AS);
   APInt Offset = APInt::getNullValue(IntPtrWidth);
 
   // Even though we don't look through PHI nodes, we could be called on an
@@ -885,7 +889,7 @@
     assert(V->getType()->isPointerTy() && "Unexpected operand type!");
   } while (Visited.insert(V));
 
-  Type *IntPtrTy = TD->getIntPtrType(V->getContext());
+  Type *IntPtrTy = TD->getIntPtrType(V->getContext(), AS);
   return cast<ConstantInt>(ConstantInt::get(IntPtrTy, Offset));
 }
 
@@ -925,7 +929,8 @@
       // size of the byval type by the target's pointer size.
       PointerType *PTy = cast<PointerType>(CS.getArgument(I)->getType());
       unsigned TypeSize = TD->getTypeSizeInBits(PTy->getElementType());
-      unsigned PointerSize = TD->getPointerSizeInBits();
+      unsigned AS = PTy->getAddressSpace();
+      unsigned PointerSize = TD->getPointerSizeInBits(AS);
       // Ceiling division.
       unsigned NumStores = (TypeSize + PointerSize - 1) / PointerSize;
 
@@ -1046,7 +1051,7 @@
     // We never want to inline functions that contain an indirectbr.  This is
     // incorrect because all the blockaddress's (in static global initializers
     // for example) would be referring to the original function, and this
-    // indirect jump would jump from the inlined copy of the function into the 
+    // indirect jump would jump from the inlined copy of the function into the
     // original function which is extremely undefined behavior.
     // FIXME: This logic isn't really right; we can safely inline functions
     // with indirectbr's as long as no other function or global references the
@@ -1115,7 +1120,7 @@
     }
   }
 
-  // If this is a noduplicate call, we can still inline as long as 
+  // If this is a noduplicate call, we can still inline as long as
   // inlining this would cause the removal of the caller (so the instruction
   // is not actually duplicated, just moved).
   if (!OnlyOneCallAndLocalLinkage && ContainsNoDuplicateCall)
Index: test/Transforms/Inline/ptr-diff.ll
===================================================================
--- test/Transforms/Inline/ptr-diff.ll
+++ test/Transforms/Inline/ptr-diff.ll
@@ -1,6 +1,6 @@
 ; RUN: opt -inline < %s -S -o - -inline-threshold=10 | FileCheck %s
 
-target datalayout = "p:32:32"
+target datalayout = "p:32:32-p1:64:64-n32"
 
 define i32 @outer1() {
 ; CHECK-LABEL: @outer1(
@@ -29,6 +29,33 @@
   ret i32 %t
 }
 
+define i32 @outer1_as1(i32 addrspace(1)* %ptr) {
+; CHECK-LABEL: @outer1_as1(
+; CHECK: call
+; CHECK: ret i32
+  %ptr1 = getelementptr inbounds i32 addrspace(1)* %ptr, i32 0
+  %ptr2 = getelementptr inbounds i32 addrspace(1)* %ptr, i32 42
+  %result = call i32 @inner1_as1(i32 addrspace(1)* %ptr1, i32 addrspace(1)* %ptr2)
+  ret i32 %result
+}
+
+; Make sure that the address space's larger size makes the ptrtoints
+; not no-ops preventing inlining
+define i32 @inner1_as1(i32 addrspace(1)* %begin, i32 addrspace(1)* %end) {
+  %begin.i = ptrtoint i32 addrspace(1)* %begin to i32
+  %end.i = ptrtoint i32 addrspace(1)* %end to i32
+  %distance = sub i32 %end.i, %begin.i
+  %icmp = icmp sle i32 %distance, 42
+  br i1 %icmp, label %then, label %else
+
+then:
+  ret i32 3
+
+else:
+  %t = load i32 addrspace(1)* %begin
+  ret i32 %t
+}
+
 ; Make sure that assertion isn't hit when ptrtoint is used with an
 ; integer size different from the pointer size
 define i32 @outer1_ptrtoint_larger() {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1251.1.patch
Type: text/x-patch
Size: 6334 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130731/4de6459d/attachment.bin>


More information about the llvm-commits mailing list