[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