[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