Optimize load from aggregate stores
deadal nix
deadalnix at gmail.com
Fri Feb 7 21:02:16 PST 2014
Here is the updated patch with test case included:
diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp
index f350b9b..c8a0ec0 100644
--- a/lib/Transforms/Scalar/GVN.cpp
+++ b/lib/Transforms/Scalar/GVN.cpp
@@ -996,11 +996,6 @@ static int AnalyzeLoadFromClobberingWrite(Type
*LoadTy, Value *LoadPtr,
static int AnalyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr,
StoreInst *DepSI,
const DataLayout &TD) {
- // Cannot handle reading from store of first-class aggregate yet.
- if (DepSI->getValueOperand()->getType()->isStructTy() ||
- DepSI->getValueOperand()->getType()->isArrayTy())
- return -1;
-
Value *StorePtr = DepSI->getPointerOperand();
uint64_t StoreSize
=TD.getTypeSizeInBits(DepSI->getValueOperand()->getType());
return AnalyzeLoadFromClobberingWrite(LoadTy, LoadPtr,
@@ -1097,6 +1092,25 @@ static Value *GetStoreValueForLoad(Value *SrcVal,
unsigned Offset,
IRBuilder<> Builder(InsertPt->getParent(), InsertPt);
+ // When facing an Aggregate, we have to find the element to fetch from.
+ while (SrcVal->getType()->isAggregateType()) {
+ if (StructType *ST = dyn_cast<StructType>(SrcVal->getType())) {
+ const StructLayout &Layout = *TD.getStructLayout(ST);
+ unsigned i = 0;
+ for (unsigned cd = 0, e = ST->getNumElements(); cd != e; ++cd) {
+ if (Layout.getElementOffsetInBits(cd) > Offset) break;
+ i = cd;
+ }
+
+ SrcVal = Builder.CreateExtractValue(SrcVal, i);
+ Offset -= Layout.getElementOffsetInBits(i);
+ } else if (ArrayType *AT = dyn_cast<ArrayType>(SrcVal->getType())) {
+ uint64_t EltSize = TD.getTypeAllocSizeInBits(AT->getElementType());
+ SrcVal = Builder.CreateExtractValue(SrcVal, Offset / EltSize);
+ Offset %= EltSize;
+ }
+ }
+
// Compute which bits of the stored value are being used by the load.
Convert
// to an integer type to start with.
if (SrcVal->getType()->getScalarType()->isPointerTy())
diff --git a/test/Transforms/GVN/aggregate_store.ll
b/test/Transforms/GVN/aggregate_store.ll
new file mode 100644
index 0000000..fc8aab4
--- /dev/null
+++ b/test/Transforms/GVN/aggregate_store.ll
@@ -0,0 +1,36 @@
+; RUN: opt -gvn -S < %s | FileCheck %s
+
+target datalayout =
+"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-f128:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+%A__vtbl = type { i8*, i32 (%A*)* }
+%A = type { %A__vtbl* }
+
+ at A__vtblZ = constant %A__vtbl { i8* null, i32 (%A*)* @A.foo }
+ at A__initZ = constant %A { %A__vtbl* @A__vtblZ }
+
+declare i8* @allocmemory(i64)
+
+define i32 @f1() {
+body:
+ %0 = tail call i8* @allocmemory(i64 8)
+ %1 = bitcast i8* %0 to %A*
+; CHECK: store %A
+ store %A { %A__vtbl* @A__vtblZ }, %A* %1, align 8
+ %2 = getelementptr inbounds %A* %1, i32 0, i32 0
+; CHECK-NOT: load %A__vtbl*
+ %vtbl.i = load %A__vtbl** %2, align 8
+ %3 = getelementptr inbounds %A__vtbl* %vtbl.i, i64 0, i32 1
+; CHECK-NOT: load i32 (%A*)*
+ %4 = load i32 (%A*)** %3, align 8
+; CHECK: tail call i32 @A.foo(%A* %1)
+ %5 = tail call i32 %4(%A* %1)
+ ret i32 %5
+}
+
+define i32 @A.foo(%A* nocapture %this) nounwind readnone {
+body:
+ ret i32 42
+}
+
2014-02-07 10:01 GMT-08:00 Adrian Prantl <aprantl at apple.com>:
>
> On Feb 6, 2014, at 22:52, deadal nix <deadalnix at gmail.com> wrote:
> >
> > I have some test cases, but I'm not sure how the LLVM test suite work
> and what is the right way to add them. I'll need some directions here to
> complete the diff.Anyway, the code :
>
> To test a change to GVN it would be best to have a .ll file with a RUN:
> line that invokes opt (with the appropriate flags for GVN) and then CHECKs
> the output with FileCheck. You can grep for "RUN: opt" in test/ for some
> examples.
> Assuming that you have source code for a testcase, you can extract an
> appropriate fragment from the output go -mllvm -print-after-all.
>
> -- adrian
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140207/364772ed/attachment.html>
More information about the llvm-commits
mailing list