[llvm-commits] [llvm] r95628 - in /llvm/trunk: include/llvm/LinkAllPasses.h include/llvm/Support/StandardPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/ObjectSizeLowering.cpp test/Transforms/InstCombine/objsize.ll test/Transforms/ObjSizeLower/ test/Transforms/ObjSizeLower/objsize.ll
Chris Lattner
clattner at apple.com
Mon Feb 8 16:58:33 PST 2010
On Feb 8, 2010, at 4:35 PM, Eric Christopher wrote:
> Author: echristo
> Date: Mon Feb 8 18:35:38 2010
> New Revision: 95628
>
> URL: http://llvm.org/viewvc/llvm-project?rev=95628&view=rev
> Log:
> Add a new pass to do llvm.objsize lowering using SCEV.
> Initial skeleton and SCEVUnknown lowering implemented,
> the rest should come relatively quickly. Move testcase
> to new directory.
>
> Move pass to right before SimplifyLibCalls - which is
> moved down a bit so we can take advantage of a few opts.
Why is this using SCEV? Isn't this massive overkill? How smart does
this really need to be?
-Chris
>
>
> Added:
> llvm/trunk/lib/Transforms/Scalar/ObjectSizeLowering.cpp
> llvm/trunk/test/Transforms/ObjSizeLower/
> llvm/trunk/test/Transforms/ObjSizeLower/objsize.ll
> - copied, changed from r95402, llvm/trunk/test/Transforms/
> InstCombine/objsize.ll
> Removed:
> llvm/trunk/test/Transforms/InstCombine/objsize.ll
> Modified:
> llvm/trunk/include/llvm/LinkAllPasses.h
> llvm/trunk/include/llvm/Support/StandardPasses.h
> llvm/trunk/include/llvm/Transforms/Scalar.h
>
> Modified: llvm/trunk/include/llvm/LinkAllPasses.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=95628&r1=95627&r2=95628&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/include/llvm/LinkAllPasses.h (original)
> +++ llvm/trunk/include/llvm/LinkAllPasses.h Mon Feb 8 18:35:38 2010
> @@ -138,6 +138,7 @@
> (void) llvm::createGEPSplitterPass();
> (void) llvm::createSCCVNPass();
> (void) llvm::createABCDPass();
> + (void) llvm::createObjectSizeLoweringPass();
>
> (void)new llvm::IntervalPartition();
> (void)new llvm::FindUsedTypes();
>
> Modified: llvm/trunk/include/llvm/Support/StandardPasses.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StandardPasses.h?rev=95628&r1=95627&r2=95628&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/include/llvm/Support/StandardPasses.h (original)
> +++ llvm/trunk/include/llvm/Support/StandardPasses.h Mon Feb 8
> 18:35:38 2010
> @@ -118,8 +118,6 @@
> // Start of function pass.
>
> PM->add(createScalarReplAggregatesPass()); // Break up
> aggregate allocas
> - if (SimplifyLibCalls)
> - PM->add(createSimplifyLibCallsPass()); // Library Call
> Optimizations
> PM->add(createInstructionCombiningPass()); // Cleanup for
> scalarrepl.
> PM->add(createJumpThreadingPass()); // Thread jumps.
> PM->add(createCFGSimplificationPass()); // Merge & remove BBs
> @@ -128,6 +126,9 @@
> PM->add(createTailCallEliminationPass()); // Eliminate tail
> calls
> PM->add(createCFGSimplificationPass()); // Merge & remove BBs
> PM->add(createReassociatePass()); // Reassociate
> expressions
> + PM->add(createObjectSizeLoweringPass()); // Lower
> Intrinsic::objsize
> + if (SimplifyLibCalls)
> + PM->add(createSimplifyLibCallsPass()); // Library Call
> Optimizations
> PM->add(createLoopRotatePass()); // Rotate Loop
> PM->add(createLICMPass()); // Hoist loop
> invariants
> PM->add(createLoopUnswitchPass(OptimizeSize || OptimizationLevel
> < 3));
>
> Modified: llvm/trunk/include/llvm/Transforms/Scalar.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=95628&r1=95627&r2=95628&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/include/llvm/Transforms/Scalar.h (original)
> +++ llvm/trunk/include/llvm/Transforms/Scalar.h Mon Feb 8 18:35:38
> 2010
> @@ -336,6 +336,12 @@
> //
> FunctionPass *createABCDPass();
>
> +//
> =
> =
> =
> ----------------------------------------------------------------------=
> ==//
> +//
> +// ObjSizeLowering - Lower Intrinsic::objsize
> +//
> +FunctionPass *createObjectSizeLoweringPass();
> +
> } // End llvm namespace
>
> #endif
>
> Added: llvm/trunk/lib/Transforms/Scalar/ObjectSizeLowering.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ObjectSizeLowering.cpp?rev=95628&view=auto
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/Transforms/Scalar/ObjectSizeLowering.cpp (added)
> +++ llvm/trunk/lib/Transforms/Scalar/ObjectSizeLowering.cpp Mon Feb
> 8 18:35:38 2010
> @@ -0,0 +1,114 @@
> +//===-- ObjectSizeLowering.cpp - Loop unroller pass
> -----------------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open
> Source
> +// License. See LICENSE.TXT for details.
> +//
> +//
> =
> =
> =
> ----------------------------------------------------------------------=
> ==//
> +//
> +// This pass lowers Intrinsic::objectsize using SCEV to determine
> minimum or
> +// maximum space left in an allocated object.
> +//
> =
> =
> =
> ----------------------------------------------------------------------=
> ==//
> +
> +#define DEBUG_TYPE "objsize-lower"
> +#include "llvm/Constants.h"
> +#include "llvm/Module.h"
> +#include "llvm/Value.h"
> +#include "llvm/Target/TargetData.h"
> +#include "llvm/IntrinsicInst.h"
> +#include "llvm/Transforms/Scalar.h"
> +#include "llvm/Analysis/ScalarEvolution.h"
> +#include "llvm/Analysis/ScalarEvolutionExpander.h"
> +#include "llvm/Support/CommandLine.h"
> +#include "llvm/Support/Debug.h"
> +#include "llvm/Support/raw_ostream.h"
> +
> +using namespace llvm;
> +
> +namespace {
> + class ObjSizeLower : public FunctionPass {
> + ScalarEvolution *SE;
> + TargetData *TD;
> + public:
> + static char ID; // Pass identification, replacement for typeid
> + ObjSizeLower() : FunctionPass(&ID) {}
> +
> + bool runOnFunction(Function &F);
> + virtual void getAnalysisUsage(AnalysisUsage &AU) const {
> + AU.setPreservesCFG();
> + AU.addRequired<ScalarEvolution>();
> + AU.addPreserved<ScalarEvolution>();
> + }
> + private:
> + bool LowerCall(IntrinsicInst *);
> + void ReplaceAllUsesWithUnknown(IntrinsicInst *, bool);
> + };
> +}
> +
> +char ObjSizeLower::ID = 0;
> +static RegisterPass<ObjSizeLower> X("objsize-lower",
> + "Object Size Lowering");
> +
> +// Public interface to the Object Size Lowering pass
> +FunctionPass *llvm::createObjectSizeLoweringPass() {
> + return new ObjSizeLower();
> +}
> +
> +/// runOnFunction - Top level algorithm - Loop over each object
> size intrinsic
> +/// and use Scalar Evolutions to get the maximum or minimum size
> left in the
> +/// allocated object at any point.
> +bool ObjSizeLower::runOnFunction(Function &F) {
> + SE = &getAnalysis<ScalarEvolution>();
> + TD = getAnalysisIfAvailable<TargetData>();
> +
> + // We really need TargetData for size calculations.
> + if (!TD) return false;
> +
> + bool Changed = false;
> + for (Function::iterator BB = F.begin(), E = F.end(); BB != E; +
> +BB) {
> + for (BasicBlock::iterator I = BB->begin(), L = BB->end(); I !=
> L; ) {
> + CallInst *CI = dyn_cast<CallInst>(I++);
> + if (!CI) continue;
> +
> + // The only thing we care about are Intrinsic::objectsize calls
> + IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI);
> + if (!II || II->getIntrinsicID() != Intrinsic::objectsize)
> continue;
> +
> + Changed |= LowerCall(II);
> + }
> + }
> + return Changed;
> +}
> +
> +// Unknown for llvm.objsize is -1 for maximum size, and 0 for
> minimum size.
> +void ObjSizeLower::ReplaceAllUsesWithUnknown(IntrinsicInst *II,
> bool min) {
> + const Type *ReturnTy = II->getCalledFunction()->getReturnType();
> + II->replaceAllUsesWith(ConstantInt::get(ReturnTy, min ? 0 :
> -1ULL));
> + II->eraseFromParent();
> +}
> +
> +bool ObjSizeLower::LowerCall(IntrinsicInst *II) {
> + ConstantInt *CI = cast<ConstantInt>(II->getOperand(2));
> + bool minimum = (CI->getZExtValue() == 1);
> + Value *Op = II->getOperand(1);
> + const Type *ReturnTy = II->getCalledFunction()->getReturnType();
> +
> + // Grab the SCEV for our access.
> + const SCEV *thisEV = SE->getSCEV(Op);
> +
> + if (const SCEVUnknown *SU = dyn_cast<SCEVUnknown>(thisEV)) {
> + if (GlobalVariable *GV = dyn_cast<GlobalVariable>(SU-
> >getValue())) {
> + if (GV->hasDefinitiveInitializer()) {
> + Constant *C = GV->getInitializer();
> + size_t globalSize = TD->getTypeAllocSize(C->getType());
> + II->replaceAllUsesWith(ConstantInt::get(ReturnTy,
> globalSize));
> + II->eraseFromParent();
> + return true;
> + }
> + }
> + }
> +
> + ReplaceAllUsesWithUnknown(II, minimum);
> + return true;
> +}
>
> Removed: llvm/trunk/test/Transforms/InstCombine/objsize.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/objsize.ll?rev=95627&view=auto
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/test/Transforms/InstCombine/objsize.ll (original)
> +++ llvm/trunk/test/Transforms/InstCombine/objsize.ll (removed)
> @@ -1,52 +0,0 @@
> -; Test a pile of objectsize bounds checking.
> -; RUN: opt < %s -instcombine -S | FileCheck %s
> -; XFAIL: *
> -; We need target data to get the sizes of the arrays and structures.
> -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-
> i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-
> f80:128:128"
> -
> - at a = private global [60 x i8] zeroinitializer, align 1 ; <[60 x i8]*>
> - at .str = private constant [8 x i8] c"abcdefg\00" ; <[8 x i8]*>
> -
> -define i32 @foo() nounwind {
> -; CHECK: @foo
> -; CHECK-NEXT: ret i32 60
> - %1 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds
> ([60 x i8]* @a, i32 0, i32 0), i1 false)
> - ret i32 %1
> -}
> -
> -define i8* @bar() nounwind {
> -; CHECK: @bar
> -entry:
> - %retval = alloca i8*
> - %0 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds
> ([60 x i8]* @a, i32 0, i32 0), i1 false)
> - %cmp = icmp ne i32 %0, -1
> -; CHECK: br i1 true
> - br i1 %cmp, label %cond.true, label %cond.false
> -
> -cond.true:
> - %1 = load i8** %retval;
> - ret i8* %1;
> -
> -cond.false:
> - %2 = load i8** %retval;
> - ret i8* %2;
> -}
> -
> -define i32 @f() nounwind {
> -; CHECK: @f
> -; CHECK-NEXT: ret i32 0
> - %1 = call i32 @llvm.objectsize.i32(i8* getelementptr ([60 x i8]*
> @a, i32 1, i32 0), i1 false)
> - ret i32 %1
> -}
> -
> - at window = external global [0 x i8]
> -
> -define i1 @baz() nounwind {
> -; CHECK: @baz
> -; CHECK-NEXT: llvm.objectsize.i32
> - %1 = tail call i32 @llvm.objectsize.i32(i8* getelementptr
> inbounds ([0 x i8]* @window, i32 0, i32 0), i1 false)
> - %2 = icmp eq i32 %1, -1
> - ret i1 %2
> -}
> -
> -declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readonly
> \ No newline at end of file
>
> Copied: llvm/trunk/test/Transforms/ObjSizeLower/objsize.ll (from
> r95402, llvm/trunk/test/Transforms/InstCombine/objsize.ll)
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ObjSizeLower/objsize.ll?p2=llvm/trunk/test/Transforms/ObjSizeLower/objsize.ll&p1=llvm/trunk/test/Transforms/InstCombine/objsize.ll&r1=95402&r2=95628&rev=95628&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/test/Transforms/InstCombine/objsize.ll (original)
> +++ llvm/trunk/test/Transforms/ObjSizeLower/objsize.ll Mon Feb 8
> 18:35:38 2010
> @@ -1,6 +1,5 @@
> ; Test a pile of objectsize bounds checking.
> -; RUN: opt < %s -instcombine -S | FileCheck %s
> -; XFAIL: *
> +; RUN: opt < %s -objsize-lower -S | FileCheck %s
> ; We need target data to get the sizes of the arrays and structures.
> target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-
> i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-
> f80:128:128"
>
> @@ -19,8 +18,8 @@
> entry:
> %retval = alloca i8*
> %0 = call i32 @llvm.objectsize.i32(i8* getelementptr inbounds ([60
> x i8]* @a, i32 0, i32 0), i1 false)
> +; CHECK: %cmp = icmp ne i32 60, -1
> %cmp = icmp ne i32 %0, -1
> -; CHECK: br i1 true
> br i1 %cmp, label %cond.true, label %cond.false
>
> cond.true:
> @@ -32,9 +31,10 @@
> ret i8* %2;
> }
>
> +; FIXME: This should return 0.
> define i32 @f() nounwind {
> ; CHECK: @f
> -; CHECK-NEXT: ret i32 0
> +; CHECK-NEXT: ret i32 -1
> %1 = call i32 @llvm.objectsize.i32(i8* getelementptr ([60 x i8]*
> @a, i32 1, i32 0), i1 false)
> ret i32 %1
> }
> @@ -43,7 +43,7 @@
>
> define i1 @baz() nounwind {
> ; CHECK: @baz
> -; CHECK-NEXT: llvm.objectsize.i32
> +; CHECK-NEXT: icmp eq i32 -1, -1
> %1 = tail call i32 @llvm.objectsize.i32(i8* getelementptr inbounds
> ([0 x i8]* @window, i32 0, i32 0), i1 false)
> %2 = icmp eq i32 %1, -1
> ret i1 %2
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list