[llvm-commits] [poolalloc] r131006 - in /poolalloc/trunk: include/assistDS/ lib/AssistDS/
Arushi Aggarwal
aggarwa4 at illinois.edu
Fri May 6 12:26:18 PDT 2011
Author: aggarwa4
Date: Fri May 6 14:26:18 2011
New Revision: 131006
URL: http://llvm.org/viewvc/llvm-project?rev=131006&view=rev
Log:
Split pass definitions into separate header files.
Added:
poolalloc/trunk/include/assistDS/ArgCast.h
poolalloc/trunk/include/assistDS/FuncSpec.h
poolalloc/trunk/include/assistDS/GEPExprArgs.h
poolalloc/trunk/include/assistDS/Int2PtrCmp.h
poolalloc/trunk/include/assistDS/LoadArgs.h
poolalloc/trunk/include/assistDS/MergeGEP.h
poolalloc/trunk/include/assistDS/SimplifyExtractValue.h
poolalloc/trunk/include/assistDS/SimplifyGEP.h
poolalloc/trunk/include/assistDS/SimplifyInsertValue.h
poolalloc/trunk/include/assistDS/StructReturnToPointer.h
poolalloc/trunk/include/assistDS/VarArgsFunc.h
poolalloc/trunk/lib/AssistDS/GEPExprArgs.cpp
poolalloc/trunk/lib/AssistDS/MergeGEP.cpp
Removed:
poolalloc/trunk/lib/AssistDS/GEPExprArg.cpp
poolalloc/trunk/lib/AssistDS/MergeArrayIndexGEP.cpp
Modified:
poolalloc/trunk/lib/AssistDS/ArgCast.cpp
poolalloc/trunk/lib/AssistDS/FuncSpec.cpp
poolalloc/trunk/lib/AssistDS/Int2PtrCmp.cpp
poolalloc/trunk/lib/AssistDS/LoadArgs.cpp
poolalloc/trunk/lib/AssistDS/SimplifyExtractValue.cpp
poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp
poolalloc/trunk/lib/AssistDS/SimplifyInsertValue.cpp
poolalloc/trunk/lib/AssistDS/StructReturnToPointer.cpp
poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp
poolalloc/trunk/lib/AssistDS/VarArgsFunc.cpp
Added: poolalloc/trunk/include/assistDS/ArgCast.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/ArgCast.h?rev=131006&view=auto
==============================================================================
--- poolalloc/trunk/include/assistDS/ArgCast.h (added)
+++ poolalloc/trunk/include/assistDS/ArgCast.h Fri May 6 14:26:18 2011
@@ -0,0 +1,34 @@
+//===-------- ArgCast.cpp - Cast Arguments to Calls -----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Convert
+// call(bitcast (.., T1 arg, ...)F to(..., T2 arg, ...))(..., T2 val, ...)
+// to
+// val1 = bitcast T2 val to T1
+// call F (..., T1 val1, ...)
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+ //
+ // Class: ArgCast
+ //
+ // Description:
+ // Implement an LLVM pass that cleans up call sites that take casted args
+ //
+ class ArgCast : public ModulePass {
+ public:
+ static char ID;
+ ArgCast() : ModulePass(&ID) {}
+ virtual bool runOnModule(Module& M);
+ };
+}
+
Added: poolalloc/trunk/include/assistDS/FuncSpec.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/FuncSpec.h?rev=131006&view=auto
==============================================================================
--- poolalloc/trunk/include/assistDS/FuncSpec.h (added)
+++ poolalloc/trunk/include/assistDS/FuncSpec.h Fri May 6 14:26:18 2011
@@ -0,0 +1,35 @@
+//===-- FuncSpec.cpp - Clone Functions With Constant Function Ptr Args ----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass clones functions that take constant function pointers as arguments
+// from some call sites. It changes those call sites to call cloned functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+ //
+ // Class: FuncSpec
+ //
+ // Description:
+ // Implement an LLVM pass that clones functions which are passed
+ // as an argument
+ //
+ //
+ class FuncSpec : public ModulePass {
+ public:
+ static char ID;
+ FuncSpec() : ModulePass(&ID) {}
+ virtual bool runOnModule(Module& M);
+ };
+}
+
Added: poolalloc/trunk/include/assistDS/GEPExprArgs.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/GEPExprArgs.h?rev=131006&view=auto
==============================================================================
--- poolalloc/trunk/include/assistDS/GEPExprArgs.h (added)
+++ poolalloc/trunk/include/assistDS/GEPExprArgs.h Fri May 6 14:26:18 2011
@@ -0,0 +1,34 @@
+//===-- GEPExprArg.cpp - Promote args if they come from GEPs -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Identify GEPs used as arguments to call sites.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+ //
+ // Class: GEPExprArgs
+ //
+ // Description:
+ // Implement an LLVM pass that clones functions which are passed GEPs
+ // as an argument
+ //
+ //
+ class GEPExprArgs : public ModulePass {
+ public:
+ static char ID;
+ GEPExprArgs() : ModulePass(&ID) {}
+ virtual bool runOnModule(Module& M);
+ };
+}
+
Added: poolalloc/trunk/include/assistDS/Int2PtrCmp.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/Int2PtrCmp.h?rev=131006&view=auto
==============================================================================
--- poolalloc/trunk/include/assistDS/Int2PtrCmp.h (added)
+++ poolalloc/trunk/include/assistDS/Int2PtrCmp.h Fri May 6 14:26:18 2011
@@ -0,0 +1,40 @@
+//===-- Int2PtrCmp.cpp - Merge inttoptr/ptrtoint --------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Remove unnecessary inttoptr casts
+// Specially ones used in just compares
+// Most cases derived from InstCombine
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Target/TargetData.h"
+
+
+namespace llvm {
+ //
+ // Class: Int2PtrCmp
+ //
+ //
+ class Int2PtrCmp : public ModulePass {
+ private:
+ TargetData * TD;
+ public:
+ static char ID;
+ Int2PtrCmp() : ModulePass(&ID) {}
+ virtual bool runOnModule(Module& M);
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<TargetData>();
+ }
+
+ };
+}
+
Added: poolalloc/trunk/include/assistDS/LoadArgs.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/LoadArgs.h?rev=131006&view=auto
==============================================================================
--- poolalloc/trunk/include/assistDS/LoadArgs.h (added)
+++ poolalloc/trunk/include/assistDS/LoadArgs.h Fri May 6 14:26:18 2011
@@ -0,0 +1,36 @@
+//===-- LoadArgs.cpp - Promote args if they came from loads ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Identify calls, that are passed arguemtns that are LoadInsts.
+// Pass the original pointer instead. Helps improve some
+// context sensitivity.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+ //
+ // Class: LoadArgs
+ //
+ // Description:
+ // Implement an LLVM pass that clones functions which are passed loads
+ // as an argument
+ //
+ //
+ class LoadArgs : public ModulePass {
+ public:
+ static char ID;
+ LoadArgs() : ModulePass(&ID) {}
+ virtual bool runOnModule(Module& M);
+ };
+}
+
Added: poolalloc/trunk/include/assistDS/MergeGEP.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/MergeGEP.h?rev=131006&view=auto
==============================================================================
--- poolalloc/trunk/include/assistDS/MergeGEP.h (added)
+++ poolalloc/trunk/include/assistDS/MergeGEP.h Fri May 6 14:26:18 2011
@@ -0,0 +1,30 @@
+//===-- MergeGEP.cpp - Merge GEPs for indexing in arrays ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Merge chained GEPs; Specially useful for arrays inside structs
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Target/TargetData.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+ //
+ // Class: MergeArrayGEP
+ //
+ class MergeArrayGEP : public ModulePass {
+ public:
+ static char ID;
+ MergeArrayGEP() : ModulePass(&ID) {}
+ virtual bool runOnModule(Module& M);
+ };
+}
+
Added: poolalloc/trunk/include/assistDS/SimplifyExtractValue.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/SimplifyExtractValue.h?rev=131006&view=auto
==============================================================================
--- poolalloc/trunk/include/assistDS/SimplifyExtractValue.h (added)
+++ poolalloc/trunk/include/assistDS/SimplifyExtractValue.h Fri May 6 14:26:18 2011
@@ -0,0 +1,31 @@
+//===-- SimplifyExtractValue.cpp - Remove extraneous extractvalue insts----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Simplify extractvalue
+//
+// Derived from InstCombine
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+ //
+ // Class: SimplifyEV
+ //
+ class SimplifyEV : public ModulePass {
+ public:
+ static char ID;
+ SimplifyEV() : ModulePass(&ID) {}
+ virtual bool runOnModule(Module& M);
+ };
+}
+
Added: poolalloc/trunk/include/assistDS/SimplifyGEP.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/SimplifyGEP.h?rev=131006&view=auto
==============================================================================
--- poolalloc/trunk/include/assistDS/SimplifyGEP.h (added)
+++ poolalloc/trunk/include/assistDS/SimplifyGEP.h Fri May 6 14:26:18 2011
@@ -0,0 +1,35 @@
+//===--------------- SimplifyGEP.cpp - Simplify GEPs types ---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Simplify GEPs with bitcasts (mostly cloned from InstCombine)
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Target/TargetData.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+ //
+ // Class: SimplifyGEP
+ //
+ class SimplifyGEP : public ModulePass {
+ private:
+ TargetData * TD;
+ public:
+ static char ID;
+ SimplifyGEP() : ModulePass(&ID) {}
+ virtual bool runOnModule(Module& M);
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<TargetData>();
+ }
+ };
+}
+
Added: poolalloc/trunk/include/assistDS/SimplifyInsertValue.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/SimplifyInsertValue.h?rev=131006&view=auto
==============================================================================
--- poolalloc/trunk/include/assistDS/SimplifyInsertValue.h (added)
+++ poolalloc/trunk/include/assistDS/SimplifyInsertValue.h Fri May 6 14:26:18 2011
@@ -0,0 +1,30 @@
+//===-- SimplifyInsertValue.cpp - Remove extraneous insertvalue insts------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Simplify insertvalue
+// Replace insertvalue by storess where possible
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+ //
+ // Class: SimplifyIV
+ //
+ class SimplifyIV : public ModulePass {
+ public:
+ static char ID;
+ SimplifyIV() : ModulePass(&ID) {}
+ virtual bool runOnModule(Module& M);
+ };
+}
+
Added: poolalloc/trunk/include/assistDS/StructReturnToPointer.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/StructReturnToPointer.h?rev=131006&view=auto
==============================================================================
--- poolalloc/trunk/include/assistDS/StructReturnToPointer.h (added)
+++ poolalloc/trunk/include/assistDS/StructReturnToPointer.h Fri May 6 14:26:18 2011
@@ -0,0 +1,30 @@
+//===-------- StructReturnToPointer.cpp ------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// For functions that return structures,
+// transform them to return a pointer to the structure instead.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+ //
+ // Class: StructRet
+ //
+ class StructRet : public ModulePass {
+ public:
+ static char ID;
+ StructRet() : ModulePass(&ID) {}
+ virtual bool runOnModule(Module& M);
+ };
+}
+
Added: poolalloc/trunk/include/assistDS/VarArgsFunc.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/assistDS/VarArgsFunc.h?rev=131006&view=auto
==============================================================================
--- poolalloc/trunk/include/assistDS/VarArgsFunc.h (added)
+++ poolalloc/trunk/include/assistDS/VarArgsFunc.h Fri May 6 14:26:18 2011
@@ -0,0 +1,32 @@
+//===-- VarArgsFunc.cpp - Simplify calls to bitcasted const funcs --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Convert calls of type
+// call(bitcast F to (...)*) ()
+// to
+// call F()
+// if the number and types of arguments passed matches.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+ //
+ // Class: VarArgsFunc
+ //
+ //
+ class VarArgsFunc : public ModulePass {
+ public:
+ static char ID;
+ VarArgsFunc() : ModulePass(&ID) {}
+ virtual bool runOnModule(Module& M);
+ };
+}
+
Modified: poolalloc/trunk/lib/AssistDS/ArgCast.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/ArgCast.cpp?rev=131006&r1=131005&r2=131006&view=diff
==============================================================================
--- poolalloc/trunk/lib/AssistDS/ArgCast.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/ArgCast.cpp Fri May 6 14:26:18 2011
@@ -14,10 +14,8 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "argcast"
-#include "llvm/Instructions.h"
+#include "assistDS/ArgCast.h"
#include "llvm/Attributes.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/FormattedStream.h"
@@ -32,144 +30,135 @@
// Pass statistics
STATISTIC(numChanged, "Number of Args bitcasted");
-namespace {
+//
+// Method: runOnModule()
+//
+// Description:
+// Entry point for this LLVM pass.
+// Search for all call sites to casted functions.
+// Check if they only differ in an argument type
+// Cast the argument, and call the original function
+//
+// Inputs:
+// M - A reference to the LLVM module to transform
+//
+// Outputs:
+// M - The transformed LLVM module.
+//
+// Return value:
+// true - The module was modified.
+// false - The module was not modified.
+//
+bool ArgCast::runOnModule(Module& M) {
+
+ std::vector<CallInst*> worklist;
+ for (Module::iterator I = M.begin(); I != M.end(); ++I)
+ if (!I->isDeclaration() && !I->mayBeOverridden())
+ // Find all uses of this function
+ for(Value::use_iterator ui = I->use_begin(), ue = I->use_end(); ui != ue; ++ui)
+ // check if is ever casted to a different function type
+ if (Constant *C = dyn_cast<Constant>(ui))
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
+ if (CE->getOpcode() == Instruction::BitCast)
+ if(CE->getOperand(0) == I)
+ if(const FunctionType *FTy = dyn_cast<FunctionType>
+ ((cast<PointerType>(CE->getType()))->getElementType())) {
+ //casting to a varargs funtion
+ if(FTy->isVarArg())
+ for(Value::use_iterator uii = CE->use_begin(),
+ uee = CE->use_end(); uii != uee; ++uii) {
+ // Find all uses of the casted value, and check if it is
+ // used in a Call Instruction
+ if (CallInst* CI = dyn_cast<CallInst>(uii)) {
+ // Check that it is the called value, and not an argument
+ if(CI->getCalledValue() != CE)
+ continue;
+ // Check that the number of arguments passed, and expected
+ // by the function are the same.
+ if(CI->getNumOperands() != I->arg_size() + 1)
+ continue;
+ // Check that the return type of the function matches that
+ // expected by the call inst(ensures that the reason for the
+ // cast is not the return type).
+ if(CI->getType() != I->getReturnType())
+ continue;
- class ArgCast : public ModulePass {
- public:
- static char ID;
- ArgCast() : ModulePass(&ID) {}
-
- //
- // Method: runOnModule()
- //
- // Description:
- // Entry point for this LLVM pass.
- // Search for all call sites to casted functions.
- // Check if they only differ in an argument type
- // Cast the argument, and call the original function
- //
- // Inputs:
- // M - A reference to the LLVM module to transform
- //
- // Outputs:
- // M - The transformed LLVM module.
- //
- // Return value:
- // true - The module was modified.
- // false - The module was not modified.
- //
- bool runOnModule(Module& M) {
-
- std::vector<CallInst*> worklist;
- for (Module::iterator I = M.begin(); I != M.end(); ++I)
- if (!I->isDeclaration() && !I->mayBeOverridden())
- // Find all uses of this function
- for(Value::use_iterator ui = I->use_begin(), ue = I->use_end(); ui != ue; ++ui)
- // check if is ever casted to a different function type
- if (Constant *C = dyn_cast<Constant>(ui))
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
- if (CE->getOpcode() == Instruction::BitCast)
- if(CE->getOperand(0) == I)
- if(const FunctionType *FTy = dyn_cast<FunctionType>
- ((cast<PointerType>(CE->getType()))->getElementType())) {
- //casting to a varargs funtion
- if(FTy->isVarArg())
- for(Value::use_iterator uii = CE->use_begin(),
- uee = CE->use_end(); uii != uee; ++uii) {
- // Find all uses of the casted value, and check if it is
- // used in a Call Instruction
- if (CallInst* CI = dyn_cast<CallInst>(uii)) {
- // Check that it is the called value, and not an argument
- if(CI->getCalledValue() != CE)
- continue;
- // Check that the number of arguments passed, and expected
- // by the function are the same.
- if(CI->getNumOperands() != I->arg_size() + 1)
- continue;
- // Check that the return type of the function matches that
- // expected by the call inst(ensures that the reason for the
- // cast is not the return type).
- if(CI->getType() != I->getReturnType())
- continue;
-
- // If so, add to worklist
- worklist.push_back(CI);
- }
- }
+ // If so, add to worklist
+ worklist.push_back(CI);
}
-
- // Proces the worklist of potential call sites to transform
- while(!worklist.empty()) {
- CallInst *CI = worklist.back();
- worklist.pop_back();
- // Get the called Function
- Function *F = cast<Function>(CI->getCalledValue()->stripPointerCasts());
- const FunctionType *FTy = F->getFunctionType();
-
- SmallVector<Value*, 8> Args;
- unsigned i =0;
- for(i =0; i< FTy->getNumParams(); ++i) {
- const Type *ArgType = CI->getOperand(i+1)->getType();
- const Type *FormalType = FTy->getParamType(i);
- // If the types for this argument match, just add it to the
- // parameter list. No cast needs to be inserted.
- if(ArgType == FormalType) {
- Args.push_back(CI->getOperand(i+1));
- }
- else if(ArgType->isPointerTy() && FormalType->isPointerTy()) {
- CastInst *CastI = CastInst::CreatePointerCast(CI->getOperand(i+1),
- FormalType, "", CI);
+ }
+ }
+
+ // Proces the worklist of potential call sites to transform
+ while(!worklist.empty()) {
+ CallInst *CI = worklist.back();
+ worklist.pop_back();
+ // Get the called Function
+ Function *F = cast<Function>(CI->getCalledValue()->stripPointerCasts());
+ const FunctionType *FTy = F->getFunctionType();
+
+ SmallVector<Value*, 8> Args;
+ unsigned i =0;
+ for(i =0; i< FTy->getNumParams(); ++i) {
+ const Type *ArgType = CI->getOperand(i+1)->getType();
+ const Type *FormalType = FTy->getParamType(i);
+ // If the types for this argument match, just add it to the
+ // parameter list. No cast needs to be inserted.
+ if(ArgType == FormalType) {
+ Args.push_back(CI->getOperand(i+1));
+ }
+ else if(ArgType->isPointerTy() && FormalType->isPointerTy()) {
+ CastInst *CastI = CastInst::CreatePointerCast(CI->getOperand(i+1),
+ FormalType, "", CI);
+ Args.push_back(CastI);
+ } else if (ArgType->isIntegerTy() && FormalType->isIntegerTy()) {
+ unsigned SrcBits = ArgType->getScalarSizeInBits();
+ unsigned DstBits = FormalType->getScalarSizeInBits();
+ if(SrcBits > DstBits) {
+ CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1),
+ FormalType, true, "", CI);
+ Args.push_back(CastI);
+ } else {
+ if(F->paramHasAttr(i+1, Attribute::SExt)) {
+ CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1),
+ FormalType, true, "", CI);
+ Args.push_back(CastI);
+ } else if(F->paramHasAttr(i+1, Attribute::ZExt)) {
+ CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1),
+ FormalType, false, "", CI);
Args.push_back(CastI);
- } else if (ArgType->isIntegerTy() && FormalType->isIntegerTy()) {
- unsigned SrcBits = ArgType->getScalarSizeInBits();
- unsigned DstBits = FormalType->getScalarSizeInBits();
- if(SrcBits > DstBits) {
- CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1),
- FormalType, true, "", CI);
- Args.push_back(CastI);
- } else {
- if(F->paramHasAttr(i+1, Attribute::SExt)) {
- CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1),
- FormalType, true, "", CI);
- Args.push_back(CastI);
- } else if(F->paramHasAttr(i+1, Attribute::ZExt)) {
- CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1),
- FormalType, false, "", CI);
- Args.push_back(CastI);
- } else {
- // Use ZExt in default case.
- // Derived from InstCombine. Also, the only reason this should happen
- // is mismatched prototypes.
- // Seen in case of integer constants which get interpreted as i32,
- // even if being used as i64.
- // TODO: is this correct?
- CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1),
- FormalType, false, "", CI);
- Args.push_back(CastI);
- }
- }
} else {
- DEBUG(ArgType->dump());
- DEBUG(FormalType->dump());
- break;
- }
- }
-
- // If we found an argument we could not cast, try the next instruction
- if(i != FTy->getNumParams())
- continue;
-
- // else replace the call instruction
- CallInst *CINew = CallInst::Create(F, Args.begin(), Args.end(), "", CI);
- CINew->setCallingConv(CI->getCallingConv());
- CINew->setAttributes(CI->getAttributes());
- CI->replaceAllUsesWith(CINew);
- CI->eraseFromParent();
- numChanged++;
+ // Use ZExt in default case.
+ // Derived from InstCombine. Also, the only reason this should happen
+ // is mismatched prototypes.
+ // Seen in case of integer constants which get interpreted as i32,
+ // even if being used as i64.
+ // TODO: is this correct?
+ CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1),
+ FormalType, false, "", CI);
+ Args.push_back(CastI);
+ }
+ }
+ } else {
+ DEBUG(ArgType->dump());
+ DEBUG(FormalType->dump());
+ break;
}
- return true;
}
- };
+
+ // If we found an argument we could not cast, try the next instruction
+ if(i != FTy->getNumParams())
+ continue;
+
+ // else replace the call instruction
+ CallInst *CINew = CallInst::Create(F, Args.begin(), Args.end(), "", CI);
+ CINew->setCallingConv(CI->getCallingConv());
+ CINew->setAttributes(CI->getAttributes());
+ CI->replaceAllUsesWith(CINew);
+ CI->eraseFromParent();
+ numChanged++;
+ }
+ return true;
}
// Pass ID variable
Modified: poolalloc/trunk/lib/AssistDS/FuncSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/FuncSpec.cpp?rev=131006&r1=131005&r2=131006&view=diff
==============================================================================
--- poolalloc/trunk/lib/AssistDS/FuncSpec.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/FuncSpec.cpp Fri May 6 14:26:18 2011
@@ -13,9 +13,8 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "funcspec"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
+#include "assistDS/FuncSpec.h"
+
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/FormattedStream.h"
@@ -30,95 +29,87 @@
// Pass statistics
STATISTIC(numCloned, "Number of Functions Cloned in FuncSpec");
STATISTIC(numReplaced, "Number of Calls Replaced");
-
-namespace {
- class FuncSpec : public ModulePass {
- public:
- static char ID;
- FuncSpec() : ModulePass(&ID) {}
- //
- // Method: runOnModule()
- //
- // Description:
- // Entry point for this LLVM pass. Search for call sites, that take functions as arguments
- // Clone those functions, and pass the clone.
- //
- // Inputs:
- // M - A reference to the LLVM module to transform
- //
- // Outputs:
- // M - The transformed LLVM module.
- //
- // Return value:
- // true - The module was modified.
- // false - The module was not modified.
- //
- bool runOnModule(Module& M) {
- std::map<CallInst*, std::vector<std::pair<unsigned, Constant*> > > cloneSites;
- std::map<std::pair<Function*, std::vector<std::pair<unsigned, Constant*> > >, Function* > toClone;
-
- for (Module::iterator I = M.begin(); I != M.end(); ++I)
- if (!I->isDeclaration() && !I->mayBeOverridden()) {
- std::vector<unsigned> FPArgs;
- for (Function::arg_iterator ii = I->arg_begin(), ee = I->arg_end();
- ii != ee; ++ii) {
- // check if this function has a FunctionType(or a pointer to) argument
- if (const PointerType* Ty = dyn_cast<PointerType>(ii->getType())) {
- if (isa<FunctionType>(Ty->getElementType())) {
- // Store the index of such an argument
- FPArgs.push_back(ii->getArgNo());
- DEBUG(errs() << "Eligible: " << I->getNameStr() << "\n");
- }
- } else if (isa<FunctionType>(ii->getType())) {
- // Store the index of such an argument
- FPArgs.push_back(ii->getArgNo());
- DEBUG(errs() << "Eligible: " << I->getNameStr() << "\n");
- }
+//
+// Method: runOnModule()
+//
+// Description:
+// Entry point for this LLVM pass. Search for call sites, that take functions as arguments
+// Clone those functions, and pass the clone.
+//
+// Inputs:
+// M - A reference to the LLVM module to transform
+//
+// Outputs:
+// M - The transformed LLVM module.
+//
+// Return value:
+// true - The module was modified.
+// false - The module was not modified.
+//
+bool FuncSpec::runOnModule(Module& M) {
+ std::map<CallInst*, std::vector<std::pair<unsigned, Constant*> > > cloneSites;
+ std::map<std::pair<Function*, std::vector<std::pair<unsigned, Constant*> > >, Function* > toClone;
+
+ for (Module::iterator I = M.begin(); I != M.end(); ++I)
+ if (!I->isDeclaration() && !I->mayBeOverridden()) {
+ std::vector<unsigned> FPArgs;
+ for (Function::arg_iterator ii = I->arg_begin(), ee = I->arg_end();
+ ii != ee; ++ii) {
+ // check if this function has a FunctionType(or a pointer to) argument
+ if (const PointerType* Ty = dyn_cast<PointerType>(ii->getType())) {
+ if (isa<FunctionType>(Ty->getElementType())) {
+ // Store the index of such an argument
+ FPArgs.push_back(ii->getArgNo());
+ DEBUG(errs() << "Eligible: " << I->getNameStr() << "\n");
}
- // Now find all call sites that it is called from
- for(Value::use_iterator ui = I->use_begin(), ue = I->use_end();
- ui != ue; ++ui) {
- if (CallInst* CI = dyn_cast<CallInst>(ui)) {
- // Check that it is the called value (and not an argument)
- if(CI->getCalledValue()->stripPointerCasts() == I) {
- std::vector<std::pair<unsigned, Constant*> > Consts;
- for (unsigned x = 0; x < FPArgs.size(); ++x)
- if (Constant* C = dyn_cast<Constant>(ui->getOperand(FPArgs.at(x) + 1))) {
- // If the argument passed, at any of the locations noted earlier
- // is a constant function, store the pair
- Consts.push_back(std::make_pair(FPArgs.at(x), C));
- }
- if (!Consts.empty()) {
- // If at least one of the arguments is a constant function,
- // we must clone the function.
- cloneSites[CI] = Consts;
- toClone[std::make_pair(I, Consts)] = 0;
- }
+ } else if (isa<FunctionType>(ii->getType())) {
+ // Store the index of such an argument
+ FPArgs.push_back(ii->getArgNo());
+ DEBUG(errs() << "Eligible: " << I->getNameStr() << "\n");
+ }
+ }
+ // Now find all call sites that it is called from
+ for(Value::use_iterator ui = I->use_begin(), ue = I->use_end();
+ ui != ue; ++ui) {
+ if (CallInst* CI = dyn_cast<CallInst>(ui)) {
+ // Check that it is the called value (and not an argument)
+ if(CI->getCalledValue()->stripPointerCasts() == I) {
+ std::vector<std::pair<unsigned, Constant*> > Consts;
+ for (unsigned x = 0; x < FPArgs.size(); ++x)
+ if (Constant* C = dyn_cast<Constant>(ui->getOperand(FPArgs.at(x) + 1))) {
+ // If the argument passed, at any of the locations noted earlier
+ // is a constant function, store the pair
+ Consts.push_back(std::make_pair(FPArgs.at(x), C));
}
+ if (!Consts.empty()) {
+ // If at least one of the arguments is a constant function,
+ // we must clone the function.
+ cloneSites[CI] = Consts;
+ toClone[std::make_pair(I, Consts)] = 0;
}
}
}
-
- numCloned += toClone.size();
-
- for (std::map<std::pair<Function*, std::vector<std::pair<unsigned, Constant*> > >, Function* >::iterator I = toClone.begin(), E = toClone.end(); I != E; ++I) {
- // Clone all the functions we need cloned
- Function* DirectF = CloneFunction(I->first.first);
- DirectF->setName(I->first.first->getNameStr() + "_SPEC");
- DirectF->setLinkage(GlobalValue::InternalLinkage);
- I->first.first->getParent()->getFunctionList().push_back(DirectF);
- I->second = DirectF;
}
+ }
- for (std::map<CallInst*, std::vector<std::pair<unsigned, Constant*> > >::iterator ii = cloneSites.begin(), ee = cloneSites.end(); ii != ee; ++ii) {
- // Transform the call sites, to call the clones
- ii->first->setOperand(0, toClone[std::make_pair(cast<Function>(ii->first->getOperand(0)), ii->second)]);
- ++numReplaced;
- }
+ numCloned += toClone.size();
- return true;
- }
- };
+ for (std::map<std::pair<Function*, std::vector<std::pair<unsigned, Constant*> > >, Function* >::iterator I = toClone.begin(), E = toClone.end(); I != E; ++I) {
+ // Clone all the functions we need cloned
+ Function* DirectF = CloneFunction(I->first.first);
+ DirectF->setName(I->first.first->getNameStr() + "_SPEC");
+ DirectF->setLinkage(GlobalValue::InternalLinkage);
+ I->first.first->getParent()->getFunctionList().push_back(DirectF);
+ I->second = DirectF;
+ }
+
+ for (std::map<CallInst*, std::vector<std::pair<unsigned, Constant*> > >::iterator ii = cloneSites.begin(), ee = cloneSites.end(); ii != ee; ++ii) {
+ // Transform the call sites, to call the clones
+ ii->first->setOperand(0, toClone[std::make_pair(cast<Function>(ii->first->getOperand(0)), ii->second)]);
+ ++numReplaced;
+ }
+
+ return true;
}
// Pass ID variable
Removed: poolalloc/trunk/lib/AssistDS/GEPExprArg.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/GEPExprArg.cpp?rev=131005&view=auto
==============================================================================
--- poolalloc/trunk/lib/AssistDS/GEPExprArg.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/GEPExprArg.cpp (removed)
@@ -1,156 +0,0 @@
-//===-- MergeGEP.cpp - Merge GEPs for indexing in arrays ------------ ----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//
-//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "gepexprargs"
-
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Instructions.h"
-#include "llvm/Constants.h"
-#include "llvm/Support/GetElementPtrTypeIterator.h"
-#include "llvm/Transforms/Utils/Cloning.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Use.h"
-#include <vector>
-#include <map>
-
-using namespace llvm;
-STATISTIC(numSimplified, "Number of Calls Modified");
-
-
-namespace {
- class GEPExprArg : public ModulePass {
- public:
- static char ID;
- GEPExprArg() : ModulePass(&ID) {}
- bool runOnModule(Module& M) {
- bool changed;
- do {
- changed = false;
- for (Module::iterator F = M.begin(); F != M.end(); ++F){
- for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
- for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
- CallInst *CI = dyn_cast<CallInst>(I++);
- if(!CI)
- continue;
-
- if(CI->hasByValArgument())
- continue;
- // if the GEP calls a function, that is externally defined,
- // or might be changed, ignore this call site.
- Function *F = CI->getCalledFunction();
-
- if (!F || (F->isDeclaration() || F->mayBeOverridden()))
- continue;
- if(F->hasStructRetAttr())
- continue;
- if(F->isVarArg())
- continue;
-
- // find the argument we must replace
- Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end();
- unsigned argNum = 1;
- for(; argNum < CI->getNumOperands();argNum++, ++ai) {
- if(ai->use_empty())
- continue;
- if (isa<GEPOperator>(CI->getOperand(argNum)))
- break;
- }
-
- // if no argument was a GEP operator to be changed
- if(ai == ae)
- continue;
-
- GEPOperator *GEP = dyn_cast<GEPOperator>(CI->getOperand(argNum));
- if(!GEP->hasAllConstantIndices())
- continue;
-
- // Construct the new Type
- // Appends the struct Type at the beginning
- std::vector<const Type*>TP;
- TP.push_back(GEP->getPointerOperand()->getType());
- for(unsigned c = 1; c < CI->getNumOperands();c++) {
- TP.push_back(CI->getOperand(c)->getType());
- }
-
- //return type is same as that of original instruction
- const FunctionType *NewFTy = FunctionType::get(CI->getType(), TP, false);
- Function *NewF;
- numSimplified++;
- if(numSimplified > 800)
- return true;
-
- NewF = Function::Create(NewFTy,
- GlobalValue::InternalLinkage,
- F->getNameStr() + ".TEST",
- &M);
-
- Function::arg_iterator NI = NewF->arg_begin();
- NI->setName("Sarg");
- ++NI;
-
- DenseMap<const Value*, Value*> ValueMap;
-
- for (Function::arg_iterator II = F->arg_begin(); NI != NewF->arg_end(); ++II, ++NI) {
- ValueMap[II] = NI;
- NI->setName(II->getName());
- }
- // Perform the cloning.
- SmallVector<ReturnInst*,100> Returns;
- CloneFunctionInto(NewF, F, ValueMap, Returns);
- std::vector<Value*> fargs;
- for(Function::arg_iterator ai = NewF->arg_begin(),
- ae= NewF->arg_end(); ai != ae; ++ai) {
- fargs.push_back(ai);
- }
-
- NewF->setAlignment(F->getAlignment());
- //Get the point to insert the GEP instr.
- NI = NewF->arg_begin();
- SmallVector<Value*, 8> Ops(CI->op_begin()+1, CI->op_end());
- Instruction *InsertPoint;
- for (BasicBlock::iterator insrt = NewF->front().begin(); isa<AllocaInst>(InsertPoint = insrt); ++insrt) {;}
-
- SmallVector<Value*, 8> Indices;
- Indices.append(GEP->op_begin()+1, GEP->op_end());
- GetElementPtrInst *GEP_new = GetElementPtrInst::Create(cast<Value>(NI), Indices.begin(), Indices.end(), "", InsertPoint);
- fargs.at(argNum)->replaceAllUsesWith(GEP_new);
- unsigned j = argNum + 1;
- for(; j < CI->getNumOperands();j++) {
- if(CI->getOperand(j) == GEP)
- fargs.at(j)->replaceAllUsesWith(GEP_new);
- }
-
- SmallVector<Value*, 8> Args;
- Args.push_back(GEP->getPointerOperand());
- for(unsigned j =1;j<CI->getNumOperands();j++) {
- Args.push_back(CI->getOperand(j));
- }
- CallInst *CallI = CallInst::Create(NewF,Args.begin(), Args.end(),"", CI);
- CallI->setCallingConv(CI->getCallingConv());
- CI->replaceAllUsesWith(CallI);
- CI->eraseFromParent();
- changed = true;
- }
- }
- }
- } while(changed);
- return true;
- }
- };
-}
-
-char GEPExprArg::ID = 0;
-static RegisterPass<GEPExprArg>
-X("gep-expr-arg", "Find GEP Exprs passed as args");
Added: poolalloc/trunk/lib/AssistDS/GEPExprArgs.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/GEPExprArgs.cpp?rev=131006&view=auto
==============================================================================
--- poolalloc/trunk/lib/AssistDS/GEPExprArgs.cpp (added)
+++ poolalloc/trunk/lib/AssistDS/GEPExprArgs.cpp Fri May 6 14:26:18 2011
@@ -0,0 +1,166 @@
+//===-- GEPExprArg.cpp - Promote args if they come from GEPs -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Identify GEPs used as arguments to call sites.
+//
+//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "gepexprargs"
+
+#include "assistDS/GEPExprArgs.h"
+#include "llvm/Constants.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Use.h"
+#include <vector>
+#include <map>
+
+// Pass statistics
+STATISTIC(numSimplified, "Number of Calls Modified");
+
+using namespace llvm;
+
+//
+// Method: runOnModule()
+//
+// Description:
+// Entry point for this LLVM pass.
+// Clone functions that take GEPs as arguments
+//
+// Inputs:
+// M - A reference to the LLVM module to transform
+//
+// Outputs:
+// M - The transformed LLVM module.
+//
+// Return value:
+// true - The module was modified.
+// false - The module was not modified.
+//
+bool GEPExprArgs::runOnModule(Module& M) {
+ bool changed;
+ do {
+ changed = false;
+ for (Module::iterator F = M.begin(); F != M.end(); ++F){
+ for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
+ for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
+ CallInst *CI = dyn_cast<CallInst>(I++);
+ if(!CI)
+ continue;
+
+ if(CI->hasByValArgument())
+ continue;
+ // if the GEP calls a function, that is externally defined,
+ // or might be changed, ignore this call site.
+ Function *F = CI->getCalledFunction();
+
+ if (!F || (F->isDeclaration() || F->mayBeOverridden()))
+ continue;
+ if(F->hasStructRetAttr())
+ continue;
+ if(F->isVarArg())
+ continue;
+
+ // find the argument we must replace
+ Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end();
+ unsigned argNum = 1;
+ for(; argNum < CI->getNumOperands();argNum++, ++ai) {
+ if(ai->use_empty())
+ continue;
+ if (isa<GEPOperator>(CI->getOperand(argNum)))
+ break;
+ }
+
+ // if no argument was a GEP operator to be changed
+ if(ai == ae)
+ continue;
+
+ GEPOperator *GEP = dyn_cast<GEPOperator>(CI->getOperand(argNum));
+ if(!GEP->hasAllConstantIndices())
+ continue;
+
+ // Construct the new Type
+ // Appends the struct Type at the beginning
+ std::vector<const Type*>TP;
+ TP.push_back(GEP->getPointerOperand()->getType());
+ for(unsigned c = 1; c < CI->getNumOperands();c++) {
+ TP.push_back(CI->getOperand(c)->getType());
+ }
+
+ //return type is same as that of original instruction
+ const FunctionType *NewFTy = FunctionType::get(CI->getType(), TP, false);
+ Function *NewF;
+ numSimplified++;
+ if(numSimplified > 800)
+ return true;
+
+ NewF = Function::Create(NewFTy,
+ GlobalValue::InternalLinkage,
+ F->getNameStr() + ".TEST",
+ &M);
+
+ Function::arg_iterator NI = NewF->arg_begin();
+ NI->setName("Sarg");
+ ++NI;
+
+ DenseMap<const Value*, Value*> ValueMap;
+
+ for (Function::arg_iterator II = F->arg_begin(); NI != NewF->arg_end(); ++II, ++NI) {
+ ValueMap[II] = NI;
+ NI->setName(II->getName());
+ }
+ // Perform the cloning.
+ SmallVector<ReturnInst*,100> Returns;
+ CloneFunctionInto(NewF, F, ValueMap, Returns);
+ std::vector<Value*> fargs;
+ for(Function::arg_iterator ai = NewF->arg_begin(),
+ ae= NewF->arg_end(); ai != ae; ++ai) {
+ fargs.push_back(ai);
+ }
+
+ NewF->setAlignment(F->getAlignment());
+ //Get the point to insert the GEP instr.
+ NI = NewF->arg_begin();
+ SmallVector<Value*, 8> Ops(CI->op_begin()+1, CI->op_end());
+ Instruction *InsertPoint;
+ for (BasicBlock::iterator insrt = NewF->front().begin(); isa<AllocaInst>(InsertPoint = insrt); ++insrt) {;}
+
+ SmallVector<Value*, 8> Indices;
+ Indices.append(GEP->op_begin()+1, GEP->op_end());
+ GetElementPtrInst *GEP_new = GetElementPtrInst::Create(cast<Value>(NI), Indices.begin(), Indices.end(), "", InsertPoint);
+ fargs.at(argNum)->replaceAllUsesWith(GEP_new);
+ unsigned j = argNum + 1;
+ for(; j < CI->getNumOperands();j++) {
+ if(CI->getOperand(j) == GEP)
+ fargs.at(j)->replaceAllUsesWith(GEP_new);
+ }
+
+ SmallVector<Value*, 8> Args;
+ Args.push_back(GEP->getPointerOperand());
+ for(unsigned j =1;j<CI->getNumOperands();j++) {
+ Args.push_back(CI->getOperand(j));
+ }
+ CallInst *CallI = CallInst::Create(NewF,Args.begin(), Args.end(),"", CI);
+ CallI->setCallingConv(CI->getCallingConv());
+ CI->replaceAllUsesWith(CallI);
+ CI->eraseFromParent();
+ changed = true;
+ }
+ }
+ }
+ } while(changed);
+ return true;
+}
+
+
+char GEPExprArgs::ID = 0;
+static RegisterPass<GEPExprArgs>
+X("gep-expr-arg", "Find GEP Exprs passed as args");
Modified: poolalloc/trunk/lib/AssistDS/Int2PtrCmp.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/Int2PtrCmp.cpp?rev=131006&r1=131005&r2=131006&view=diff
==============================================================================
--- poolalloc/trunk/lib/AssistDS/Int2PtrCmp.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/Int2PtrCmp.cpp Fri May 6 14:26:18 2011
@@ -6,6 +6,7 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
// Remove unnecessary inttoptr casts
// Specially ones used in just compares
// Most cases derived from InstCombine
@@ -13,15 +14,11 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "int2ptr-cmp"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Transforms/Utils/Cloning.h"
+#include "assistDS/Int2PtrCmp.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/PatternMatch.h"
-#include "llvm/Target/TargetData.h"
#include <set>
#include <map>
@@ -30,71 +27,61 @@
using namespace llvm;
using namespace PatternMatch;
-namespace {
- class Int2PtrCmp : public ModulePass {
- private:
- TargetData * TD;
- public:
- static char ID;
- Int2PtrCmp() : ModulePass(&ID) {}
-
- //
- // Method: runOnModule()
- //
- // Description:
- // Entry point for this LLVM pass.
- // Remove unnecessary inttoptr instructions.
- //
- // Inputs:
- // M - A reference to the LLVM module to transform
- //
- // Outputs:
- // M - The transformed LLVM module.
- //
- // Return value:
- // true - The module was modified.
- // false - The module was not modified.
- //
- bool runOnModule(Module& M) {
- TD = &getAnalysis<TargetData>();
- for (Module::iterator F = M.begin(); F != M.end(); ++F) {
- for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
- for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
- // ptrtoint(inttoptr ty Y) to ty -> Y
- if(PtrToIntInst *P2I = dyn_cast<PtrToIntInst>(I++)) {
- if(IntToPtrInst *I2P = dyn_cast<IntToPtrInst>(P2I->getOperand(0))) {
- if(I2P->getSrcTy() == P2I->getDestTy()){
- P2I->replaceAllUsesWith(I2P->getOperand(0));
- P2I->eraseFromParent();
- if(I2P->use_empty()) {
- // If this is the only use of the cast delete it.
- I2P->eraseFromParent();
- }
- }
+//
+// Method: runOnModule()
+//
+// Description:
+// Entry point for this LLVM pass.
+// Remove unnecessary inttoptr instructions.
+//
+// Inputs:
+// M - A reference to the LLVM module to transform
+//
+// Outputs:
+// M - The transformed LLVM module.
+//
+// Return value:
+// true - The module was modified.
+// false - The module was not modified.
+//
+bool Int2PtrCmp::runOnModule(Module& M) {
+ TD = &getAnalysis<TargetData>();
+ for (Module::iterator F = M.begin(); F != M.end(); ++F) {
+ for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
+ for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
+ // ptrtoint(inttoptr ty Y) to ty -> Y
+ if(PtrToIntInst *P2I = dyn_cast<PtrToIntInst>(I++)) {
+ if(IntToPtrInst *I2P = dyn_cast<IntToPtrInst>(P2I->getOperand(0))) {
+ if(I2P->getSrcTy() == P2I->getDestTy()){
+ P2I->replaceAllUsesWith(I2P->getOperand(0));
+ P2I->eraseFromParent();
+ if(I2P->use_empty()) {
+ // If this is the only use of the cast delete it.
+ I2P->eraseFromParent();
}
}
}
- for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
- //icmp pred inttoptr(X), null -> icmp pred X 0
- if(ICmpInst *CI = dyn_cast<ICmpInst>(I++)) {
- Value *Op0 = CI->getOperand(0);
- Value *Op1 = CI->getOperand(1);
- if (Constant *RHSC = dyn_cast<Constant>(Op1)) {
- if (Instruction *LHSI = dyn_cast<Instruction>(Op0)){
- if(LHSI->getOpcode() == Instruction::IntToPtr) {
- if (RHSC->isNullValue() && TD &&
- TD->getIntPtrType(RHSC->getContext()) ==
- LHSI->getOperand(0)->getType()){
- ICmpInst *CI_new = new ICmpInst(CI, CI->getPredicate(), LHSI->getOperand(0),
- Constant::getNullValue(LHSI->getOperand(0)->getType()));
-
- CI->replaceAllUsesWith(CI_new);
- CI->eraseFromParent();
- if(LHSI->use_empty()) {
- // If this is the only use of the cast delete it.
- LHSI->eraseFromParent();
- }
- }
+ }
+ }
+ for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
+ //icmp pred inttoptr(X), null -> icmp pred X 0
+ if(ICmpInst *CI = dyn_cast<ICmpInst>(I++)) {
+ Value *Op0 = CI->getOperand(0);
+ Value *Op1 = CI->getOperand(1);
+ if (Constant *RHSC = dyn_cast<Constant>(Op1)) {
+ if (Instruction *LHSI = dyn_cast<Instruction>(Op0)){
+ if(LHSI->getOpcode() == Instruction::IntToPtr) {
+ if (RHSC->isNullValue() && TD &&
+ TD->getIntPtrType(RHSC->getContext()) ==
+ LHSI->getOperand(0)->getType()){
+ ICmpInst *CI_new = new ICmpInst(CI, CI->getPredicate(), LHSI->getOperand(0),
+ Constant::getNullValue(LHSI->getOperand(0)->getType()));
+
+ CI->replaceAllUsesWith(CI_new);
+ CI->eraseFromParent();
+ if(LHSI->use_empty()) {
+ // If this is the only use of the cast delete it.
+ LHSI->eraseFromParent();
}
}
}
@@ -102,94 +89,91 @@
}
}
}
+ }
+ }
- for (Module::iterator F = M.begin(); F != M.end(); ++F) {
- for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
- for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
- if(ICmpInst *ICI = dyn_cast<ICmpInst>(I++)) {
- Value *Op0 = ICI->getOperand(0);
- Value *Op1 = ICI->getOperand(1);
- if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
- // Since the RHS is a ConstantInt (CI), if the left hand side is an
- // instruction, see if that instruction also has constants so that the
- // instruction can be folded into the icmp
- if (Instruction *LHSI = dyn_cast<Instruction>(Op0)){
- if(LHSI->getOpcode() == Instruction::Or) {
- if (!ICI->isEquality() || !CI->isNullValue() || !LHSI->hasOneUse())
- break;
- Value *P, *Q, *R;
- if (match(LHSI, m_Or(m_PtrToInt(m_Value(P)), m_PtrToInt(m_Value(Q))))) {
- // Simplify icmp eq (or (ptrtoint P), (ptrtoint Q)), 0
- // -> and (icmp eq P, null), (icmp eq Q, null).
- Value *ICIP = new ICmpInst(ICI, ICI->getPredicate(), P,
- Constant::getNullValue(P->getType()));
- Value *ICIQ = new ICmpInst(ICI, ICI->getPredicate(), Q,
- Constant::getNullValue(Q->getType()));
- Instruction *Op;
- if (ICI->getPredicate() == ICmpInst::ICMP_EQ)
- Op = BinaryOperator::CreateAnd(ICIP, ICIQ,"",ICI);
- else
- Op = BinaryOperator::CreateOr(ICIP, ICIQ, "", ICI);
- ICI->replaceAllUsesWith(Op);
-
- } else if(match(LHSI, m_Or(m_Or(m_PtrToInt(m_Value(P)),
- m_PtrToInt(m_Value(Q))),
- m_PtrToInt(m_Value(R))))) {
- // Simplify icmp eq (or (or (ptrtoint P), (ptrtoint Q)), ptrtoint(R)), 0
- // -> and (and (icmp eq P, null), (icmp eq Q, null)), (icmp eq R, null).
- Value *ICIP = new ICmpInst(ICI, ICI->getPredicate(), P,
- Constant::getNullValue(P->getType()));
- Value *ICIQ = new ICmpInst(ICI, ICI->getPredicate(), Q,
- Constant::getNullValue(Q->getType()));
- Value *ICIR = new ICmpInst(ICI, ICI->getPredicate(), R,
- Constant::getNullValue(R->getType()));
- Instruction *Op;
- if (ICI->getPredicate() == ICmpInst::ICMP_EQ)
- Op = BinaryOperator::CreateAnd(ICIP, ICIQ,"",ICI);
- else
- Op = BinaryOperator::CreateOr(ICIP, ICIQ, "", ICI);
-
- if (ICI->getPredicate() == ICmpInst::ICMP_EQ)
- Op = BinaryOperator::CreateAnd(Op, ICIR,"",ICI);
- else
- Op = BinaryOperator::CreateOr(Op, ICIR, "", ICI);
- ICI->replaceAllUsesWith(Op);
-
- } else if(match(LHSI, m_Or(m_PtrToInt(m_Value(Q)), m_Or(
- m_PtrToInt(m_Value(P)), m_PtrToInt(m_Value(R)))))) {
- // Simplify icmp eq (or (ptrtoint P), or((ptrtoint Q), ptrtoint(R))), 0
- // -> and (icmp eq P, null), (and (icmp eq Q, null), (icmp eq R, null)).
- Value *ICIP = new ICmpInst(ICI, ICI->getPredicate(), P,
- Constant::getNullValue(P->getType()));
- Value *ICIQ = new ICmpInst(ICI, ICI->getPredicate(), Q,
- Constant::getNullValue(Q->getType()));
- Value *ICIR = new ICmpInst(ICI, ICI->getPredicate(), R,
- Constant::getNullValue(R->getType()));
- Instruction *Op;
- if (ICI->getPredicate() == ICmpInst::ICMP_EQ)
- Op = BinaryOperator::CreateAnd(ICIP, ICIQ,"",ICI);
- else
- Op = BinaryOperator::CreateOr(ICIP, ICIQ, "", ICI);
-
- if (ICI->getPredicate() == ICmpInst::ICMP_EQ)
- Op = BinaryOperator::CreateAnd(Op, ICIR,"",ICI);
- else
- Op = BinaryOperator::CreateOr(Op, ICIR, "", ICI);
- ICI->replaceAllUsesWith(Op);
- }
- }
+ for (Module::iterator F = M.begin(); F != M.end(); ++F) {
+ for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
+ for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
+ if(ICmpInst *ICI = dyn_cast<ICmpInst>(I++)) {
+ Value *Op0 = ICI->getOperand(0);
+ Value *Op1 = ICI->getOperand(1);
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
+ // Since the RHS is a ConstantInt (CI), if the left hand side is an
+ // instruction, see if that instruction also has constants so that the
+ // instruction can be folded into the icmp
+ if (Instruction *LHSI = dyn_cast<Instruction>(Op0)){
+ if(LHSI->getOpcode() == Instruction::Or) {
+ if (!ICI->isEquality() || !CI->isNullValue() || !LHSI->hasOneUse())
+ break;
+ Value *P, *Q, *R;
+ if (match(LHSI, m_Or(m_PtrToInt(m_Value(P)), m_PtrToInt(m_Value(Q))))) {
+ // Simplify icmp eq (or (ptrtoint P), (ptrtoint Q)), 0
+ // -> and (icmp eq P, null), (icmp eq Q, null).
+ Value *ICIP = new ICmpInst(ICI, ICI->getPredicate(), P,
+ Constant::getNullValue(P->getType()));
+ Value *ICIQ = new ICmpInst(ICI, ICI->getPredicate(), Q,
+ Constant::getNullValue(Q->getType()));
+ Instruction *Op;
+ if (ICI->getPredicate() == ICmpInst::ICMP_EQ)
+ Op = BinaryOperator::CreateAnd(ICIP, ICIQ,"",ICI);
+ else
+ Op = BinaryOperator::CreateOr(ICIP, ICIQ, "", ICI);
+ ICI->replaceAllUsesWith(Op);
+
+ } else if(match(LHSI, m_Or(m_Or(m_PtrToInt(m_Value(P)),
+ m_PtrToInt(m_Value(Q))),
+ m_PtrToInt(m_Value(R))))) {
+ // Simplify icmp eq (or (or (ptrtoint P), (ptrtoint Q)), ptrtoint(R)), 0
+ // -> and (and (icmp eq P, null), (icmp eq Q, null)), (icmp eq R, null).
+ Value *ICIP = new ICmpInst(ICI, ICI->getPredicate(), P,
+ Constant::getNullValue(P->getType()));
+ Value *ICIQ = new ICmpInst(ICI, ICI->getPredicate(), Q,
+ Constant::getNullValue(Q->getType()));
+ Value *ICIR = new ICmpInst(ICI, ICI->getPredicate(), R,
+ Constant::getNullValue(R->getType()));
+ Instruction *Op;
+ if (ICI->getPredicate() == ICmpInst::ICMP_EQ)
+ Op = BinaryOperator::CreateAnd(ICIP, ICIQ,"",ICI);
+ else
+ Op = BinaryOperator::CreateOr(ICIP, ICIQ, "", ICI);
+
+ if (ICI->getPredicate() == ICmpInst::ICMP_EQ)
+ Op = BinaryOperator::CreateAnd(Op, ICIR,"",ICI);
+ else
+ Op = BinaryOperator::CreateOr(Op, ICIR, "", ICI);
+ ICI->replaceAllUsesWith(Op);
+
+ } else if(match(LHSI, m_Or(m_PtrToInt(m_Value(Q)), m_Or(
+ m_PtrToInt(m_Value(P)), m_PtrToInt(m_Value(R)))))) {
+ // Simplify icmp eq (or (ptrtoint P), or((ptrtoint Q), ptrtoint(R))), 0
+ // -> and (icmp eq P, null), (and (icmp eq Q, null), (icmp eq R, null)).
+ Value *ICIP = new ICmpInst(ICI, ICI->getPredicate(), P,
+ Constant::getNullValue(P->getType()));
+ Value *ICIQ = new ICmpInst(ICI, ICI->getPredicate(), Q,
+ Constant::getNullValue(Q->getType()));
+ Value *ICIR = new ICmpInst(ICI, ICI->getPredicate(), R,
+ Constant::getNullValue(R->getType()));
+ Instruction *Op;
+ if (ICI->getPredicate() == ICmpInst::ICMP_EQ)
+ Op = BinaryOperator::CreateAnd(ICIP, ICIQ,"",ICI);
+ else
+ Op = BinaryOperator::CreateOr(ICIP, ICIQ, "", ICI);
+
+ if (ICI->getPredicate() == ICmpInst::ICMP_EQ)
+ Op = BinaryOperator::CreateAnd(Op, ICIR,"",ICI);
+ else
+ Op = BinaryOperator::CreateOr(Op, ICIR, "", ICI);
+ ICI->replaceAllUsesWith(Op);
}
}
}
}
}
}
- return true;
- }
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<TargetData>();
}
- };
+ }
+ return true;
}
// Pass ID variable
Modified: poolalloc/trunk/lib/AssistDS/LoadArgs.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/LoadArgs.cpp?rev=131006&r1=131005&r2=131006&view=diff
==============================================================================
--- poolalloc/trunk/lib/AssistDS/LoadArgs.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/LoadArgs.cpp Fri May 6 14:26:18 2011
@@ -1,4 +1,4 @@
-//===-- MergeGEP.cpp - Merge GEPs for indexing in arrays ------------ ----===//
+//===-- LoadArgs.cpp - Promote args if they came from loads ---------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,14 +7,14 @@
//
//===----------------------------------------------------------------------===//
//
+// Identify calls, that are passed arguments that are LoadInsts.
+// Pass the original pointer instead. Helps improve some
+// context sensitivity.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "ld-args"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Instructions.h"
+#include "assistDS/LoadArgs.h"
#include "llvm/Constants.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Transforms/Utils/Cloning.h"
@@ -25,142 +25,153 @@
#include <vector>
#include <map>
-using namespace llvm;
+// Pass statistics
STATISTIC(numSimplified, "Number of Calls Modified");
+using namespace llvm;
+
+//
+// Method: runOnModule()
+//
+// Description:
+// Entry point for this LLVM pass.
+// Clone functions that take LoadInsts as arguments
+//
+// Inputs:
+// M - A reference to the LLVM module to transform
+//
+// Outputs:
+// M - The transformed LLVM module.
+//
+// Return value:
+// true - The module was modified.
+// false - The module was not modified.
+//
+bool LoadArgs::runOnModule(Module& M) {
+ bool changed;
+ do {
+ changed = false;
+ for (Module::iterator F = M.begin(); F != M.end(); ++F){
+ for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
+ for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
+ CallInst *CI = dyn_cast<CallInst>(I++);
+ if(!CI)
+ continue;
+
+ if(CI->hasByValArgument())
+ continue;
+ // if the GEP calls a function, that is externally defined,
+ // or might be changed, ignore this call site.
+ Function *F = CI->getCalledFunction();
+
+ if (!F || (F->isDeclaration() || F->mayBeOverridden()))
+ continue;
+ if(F->hasStructRetAttr())
+ continue;
+ if(F->isVarArg())
+ continue;
+
+ // find the argument we must replace
+ Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end();
+ unsigned argNum = 1;
+ for(; argNum < CI->getNumOperands();argNum++, ++ai) {
+ if(ai->use_empty())
+ continue;
+ if(F->paramHasAttr(argNum, Attribute::SExt) ||
+ F->paramHasAttr(argNum, Attribute::ZExt))
+ continue;
+ if (isa<LoadInst>(CI->getOperand(argNum)))
+ break;
+ }
+
+ // if no argument was a GEP operator to be changed
+ if(ai == ae)
+ continue;
+
+ LoadInst *LI = dyn_cast<LoadInst>(CI->getOperand(argNum));
+ if(LI->getParent() != CI->getParent())
+ continue;
+ // Also check that there is no store after the load.
+ // TODO: Check if the load/store do not alias.
+ BasicBlock::iterator bii = LI->getParent()->begin();
+ Instruction *BII = bii;
+ while(BII != LI) {
+ ++bii;
+ BII = bii;
+ }
+ while(BII != CI) {
+ if(isa<StoreInst>(BII))
+ break;
+ ++bii;
+ BII = bii;
+ }
+ if(isa<StoreInst>(bii)){
+ continue;
+ }
+
+ // Construct the new Type
+ // Appends the struct Type at the beginning
+ std::vector<const Type*>TP;
+ TP.push_back(LI->getOperand(0)->getType());
+ for(unsigned c = 1; c < CI->getNumOperands();c++) {
+ TP.push_back(CI->getOperand(c)->getType());
+ }
+
+ //return type is same as that of original instruction
+ const FunctionType *NewFTy = FunctionType::get(CI->getType(), TP, false);
+ numSimplified++;
+ if(numSimplified > 400)
+ return true;
+
+ Function *NewF = Function::Create(NewFTy,
+ GlobalValue::InternalLinkage,
+ F->getNameStr() + ".TEST",
+ &M);
+
+ Function::arg_iterator NI = NewF->arg_begin();
+ NI->setName("Sarg");
+ ++NI;
+
+ DenseMap<const Value*, Value*> ValueMap;
+
+ for (Function::arg_iterator II = F->arg_begin(); NI != NewF->arg_end(); ++II, ++NI) {
+ ValueMap[II] = NI;
+ NI->setName(II->getName());
+ }
+ // Perform the cloning.
+ SmallVector<ReturnInst*,100> Returns;
+ CloneFunctionInto(NewF, F, ValueMap, Returns);
+ std::vector<Value*> fargs;
+ for(Function::arg_iterator ai = NewF->arg_begin(),
+ ae= NewF->arg_end(); ai != ae; ++ai) {
+ fargs.push_back(ai);
+ }
-namespace {
- class LoadArgs : public ModulePass {
- public:
- static char ID;
- LoadArgs() : ModulePass(&ID) {}
- bool runOnModule(Module& M) {
- bool changed;
- do {
- changed = false;
- for (Module::iterator F = M.begin(); F != M.end(); ++F){
- for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
- for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
- CallInst *CI = dyn_cast<CallInst>(I++);
- if(!CI)
- continue;
-
- if(CI->hasByValArgument())
- continue;
- // if the GEP calls a function, that is externally defined,
- // or might be changed, ignore this call site.
- Function *F = CI->getCalledFunction();
-
- if (!F || (F->isDeclaration() || F->mayBeOverridden()))
- continue;
- if(F->hasStructRetAttr())
- continue;
- if(F->isVarArg())
- continue;
-
- // find the argument we must replace
- Function::arg_iterator ai = F->arg_begin(), ae = F->arg_end();
- unsigned argNum = 1;
- for(; argNum < CI->getNumOperands();argNum++, ++ai) {
- if(ai->use_empty())
- continue;
- if(F->paramHasAttr(argNum, Attribute::SExt) ||
- F->paramHasAttr(argNum, Attribute::ZExt))
- continue;
- if (isa<LoadInst>(CI->getOperand(argNum)))
- break;
- }
-
- // if no argument was a GEP operator to be changed
- if(ai == ae)
- continue;
-
- LoadInst *LI = dyn_cast<LoadInst>(CI->getOperand(argNum));
- if(LI->getParent() != CI->getParent())
- continue;
- // Also check that there is no store after the load.
- // TODO: Check if the load/store do not alias.
- BasicBlock::iterator bii = LI->getParent()->begin();
- Instruction *BII = bii;
- while(BII != LI) {
- ++bii;
- BII = bii;
- }
- while(BII != CI) {
- if(isa<StoreInst>(BII))
- break;
- ++bii;
- BII = bii;
- }
- if(isa<StoreInst>(bii)){
- continue;
- }
-
- // Construct the new Type
- // Appends the struct Type at the beginning
- std::vector<const Type*>TP;
- TP.push_back(LI->getOperand(0)->getType());
- for(unsigned c = 1; c < CI->getNumOperands();c++) {
- TP.push_back(CI->getOperand(c)->getType());
- }
-
- //return type is same as that of original instruction
- const FunctionType *NewFTy = FunctionType::get(CI->getType(), TP, false);
- numSimplified++;
- if(numSimplified > 400)
- return true;
-
- Function *NewF = Function::Create(NewFTy,
- GlobalValue::InternalLinkage,
- F->getNameStr() + ".TEST",
- &M);
-
- Function::arg_iterator NI = NewF->arg_begin();
- NI->setName("Sarg");
- ++NI;
-
- DenseMap<const Value*, Value*> ValueMap;
-
- for (Function::arg_iterator II = F->arg_begin(); NI != NewF->arg_end(); ++II, ++NI) {
- ValueMap[II] = NI;
- NI->setName(II->getName());
- }
- // Perform the cloning.
- SmallVector<ReturnInst*,100> Returns;
- CloneFunctionInto(NewF, F, ValueMap, Returns);
- std::vector<Value*> fargs;
- for(Function::arg_iterator ai = NewF->arg_begin(),
- ae= NewF->arg_end(); ai != ae; ++ai) {
- fargs.push_back(ai);
- }
-
- NewF->setAlignment(F->getAlignment());
- //Get the point to insert the GEP instr.
- NI = NewF->arg_begin();
- SmallVector<Value*, 8> Ops(CI->op_begin()+1, CI->op_end());
- Instruction *InsertPoint;
- for (BasicBlock::iterator insrt = NewF->front().begin(); isa<AllocaInst>(InsertPoint = insrt); ++insrt) {;}
-
- LoadInst *LI_new = new LoadInst(cast<Value>(NI), "", InsertPoint);
- fargs.at(argNum)->replaceAllUsesWith(LI_new);
-
- SmallVector<Value*, 8> Args;
- Args.push_back(LI->getOperand(0));
- for(unsigned j =1;j<CI->getNumOperands();j++) {
- Args.push_back(CI->getOperand(j));
- }
- CallInst *CallI = CallInst::Create(NewF,Args.begin(), Args.end(),"", CI);
- CallI->setCallingConv(CI->getCallingConv());
- CI->replaceAllUsesWith(CallI);
- CI->eraseFromParent();
- changed = true;
- }
+ NewF->setAlignment(F->getAlignment());
+ //Get the point to insert the GEP instr.
+ NI = NewF->arg_begin();
+ SmallVector<Value*, 8> Ops(CI->op_begin()+1, CI->op_end());
+ Instruction *InsertPoint;
+ for (BasicBlock::iterator insrt = NewF->front().begin(); isa<AllocaInst>(InsertPoint = insrt); ++insrt) {;}
+
+ LoadInst *LI_new = new LoadInst(cast<Value>(NI), "", InsertPoint);
+ fargs.at(argNum)->replaceAllUsesWith(LI_new);
+
+ SmallVector<Value*, 8> Args;
+ Args.push_back(LI->getOperand(0));
+ for(unsigned j =1;j<CI->getNumOperands();j++) {
+ Args.push_back(CI->getOperand(j));
}
+ CallInst *CallI = CallInst::Create(NewF,Args.begin(), Args.end(),"", CI);
+ CallI->setCallingConv(CI->getCallingConv());
+ CI->replaceAllUsesWith(CallI);
+ CI->eraseFromParent();
+ changed = true;
}
- } while(changed);
- return true;
+ }
}
- };
+ } while(changed);
+ return true;
}
char LoadArgs::ID = 0;
Removed: poolalloc/trunk/lib/AssistDS/MergeArrayIndexGEP.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/MergeArrayIndexGEP.cpp?rev=131005&view=auto
==============================================================================
--- poolalloc/trunk/lib/AssistDS/MergeArrayIndexGEP.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/MergeArrayIndexGEP.cpp (removed)
@@ -1,164 +0,0 @@
-//===-- MergeArrayIndexGEP.cpp - Merge GEPs for indexing in arrays --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Merge chained GEPs; Specially useful for arrays inside structs
-//
-//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "merge-gep"
-
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Instructions.h"
-#include "llvm/Constants.h"
-#include "llvm/Support/GetElementPtrTypeIterator.h"
-#include "llvm/Transforms/Utils/Cloning.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/Debug.h"
-
-#include <vector>
-// Pass statistics
-STATISTIC(numMerged, "Number of GEPs merged");
-
-using namespace llvm;
-
-namespace {
- class MergeArrayGEP : public ModulePass {
- public:
- static char ID;
- MergeArrayGEP() : ModulePass(&ID) {}
- //
- // Method: runOnModule()
- //
- // Description:
- // Entry point for this LLVM pass.
- // Merge chained GEPs into a single GEP
- //
- // Inputs:
- // M - A reference to the LLVM module to transform
- //
- // Outputs:
- // M - The transformed LLVM module.
- //
- // Return value:
- // true - The module was modified.
- // false - The module was not modified.
- //
- bool runOnModule(Module& M) {
- bool changed;
- do {
- changed = false;
- for (Module::iterator F = M.begin(); F != M.end(); ++F){
- for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
- for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
- GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(I++);
- if(GEP == NULL)
- continue;
- simplifyGEP(GEP);
- }
- }
- }
- } while(changed);
- return true;
- }
-
- //
- // Method: simplifyGEP()
- //
- // Description:
- // Check if this GEP's pointer argument is a GEP(Inst/ConstExpr)
- // If so check if we can merge the two GEPs into a single GEP
- //
- // Inputs:
- // GEP - A pointer to the GEP to simplify
- //
- static void simplifyGEP(GetElementPtrInst *GEP) {
- Value *PtrOp = GEP->getOperand(0);
- if (GEPOperator *Src = dyn_cast<GEPOperator>(PtrOp)) {
- // Note that if our source is a gep chain itself that we wait for that
- // chain to be resolved before we perform this transformation. This
- // avoids us creating a TON of code in some cases.
- //
- if (GetElementPtrInst *SrcGEP =
- dyn_cast<GetElementPtrInst>(Src->getOperand(0)))
- if (SrcGEP->getNumOperands() == 2)
- return; // Wait until our source is folded to completion.
-
- SmallVector<Value*, 8> Indices;
-
- // Find out whether the last index in the source GEP is a sequential idx.
- bool EndsWithSequential = false;
- for (gep_type_iterator I = gep_type_begin(*Src), E = gep_type_end(*Src);
- I != E; ++I)
- EndsWithSequential = !(*I)->isStructTy();
-
- // Can we combine the two pointer arithmetics offsets?
- if (EndsWithSequential) {
- // Replace: gep (gep %P, long B), long A, ...
- // With: T = long A+B; gep %P, T, ...
- //
- Value *Sum;
- Value *SO1 = Src->getOperand(Src->getNumOperands()-1);
- Value *GO1 = GEP->getOperand(1);
- if (SO1 == Constant::getNullValue(SO1->getType())) {
- Sum = GO1;
- } else if (GO1 == Constant::getNullValue(GO1->getType())) {
- Sum = SO1;
- } else {
- // If they aren't the same type, then the input hasn't been processed
- // by the loop above yet (which canonicalizes sequential index types to
- // intptr_t). Just avoid transforming this until the input has been
- // normalized.
- if (SO1->getType() != GO1->getType())
- return;
- Sum = llvm::BinaryOperator::Create(BinaryOperator::Add,
- SO1, GO1,
- PtrOp->getName()+".sum",GEP);
- }
-
- // Update the GEP in place if possible.
- if (Src->getNumOperands() == 2) {
- GEP->setOperand(0, Src->getOperand(0));
- GEP->setOperand(1, Sum);
- numMerged++;
- return;
- }
- Indices.append(Src->op_begin()+1, Src->op_end()-1);
- Indices.push_back(Sum);
- Indices.append(GEP->op_begin()+2, GEP->op_end());
- } else if (isa<Constant>(GEP->idx_begin()) &&
- cast<Constant>(GEP->idx_begin())->isNullValue() &&
- Src->getNumOperands() != 1) {
- // Otherwise we can do the fold if the first index of the GEP is a zero
- Indices.append(Src->op_begin()+1, Src->op_end());
- Indices.append(GEP->idx_begin()+1, GEP->idx_end());
- }
-
- if (!Indices.empty()){
- GetElementPtrInst *GEPNew = (GEP->isInBounds() && Src->isInBounds()) ?
- GetElementPtrInst::CreateInBounds(Src->getOperand(0), Indices.begin(),
- Indices.end(), GEP->getName(), GEP) :
- GetElementPtrInst::Create(Src->getOperand(0), Indices.begin(),
- Indices.end(), GEP->getName(), GEP);
- numMerged++;
- GEP->replaceAllUsesWith(GEPNew);
- GEP->eraseFromParent();
- }
- }
- }
- };
-}
-
-// Pass ID variable
-char MergeArrayGEP::ID = 0;
-
-// Register the pass
-static RegisterPass<MergeArrayGEP>
-X("mergearrgep", "Merge GEPs for arrays indexing");
Added: poolalloc/trunk/lib/AssistDS/MergeGEP.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/MergeGEP.cpp?rev=131006&view=auto
==============================================================================
--- poolalloc/trunk/lib/AssistDS/MergeGEP.cpp (added)
+++ poolalloc/trunk/lib/AssistDS/MergeGEP.cpp Fri May 6 14:26:18 2011
@@ -0,0 +1,159 @@
+//===-- MergeGEP.cpp - Merge GEPs for indexing in arrays ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Merge chained GEPs; Specially useful for arrays inside structs
+//
+//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "merge-gep"
+
+#include "assistDS/MergeGEP.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Instructions.h"
+#include "llvm/Constants.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/Debug.h"
+
+#include <vector>
+// Pass statistics
+STATISTIC(numMerged, "Number of GEPs merged");
+
+using namespace llvm;
+
+static void simplifyGEP(GetElementPtrInst *GEP);
+//
+// Method: runOnModule()
+//
+// Description:
+// Entry point for this LLVM pass.
+// Merge chained GEPs into a single GEP
+//
+// Inputs:
+// M - A reference to the LLVM module to transform
+//
+// Outputs:
+// M - The transformed LLVM module.
+//
+// Return value:
+// true - The module was modified.
+// false - The module was not modified.
+//
+bool MergeArrayGEP::runOnModule(Module& M) {
+ bool changed;
+ do {
+ changed = false;
+ for (Module::iterator F = M.begin(); F != M.end(); ++F){
+ for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
+ for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
+ GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(I++);
+ if(GEP == NULL)
+ continue;
+ simplifyGEP(GEP);
+ }
+ }
+ }
+ } while(changed);
+ return true;
+}
+
+//
+// Method: simplifyGEP()
+//
+// Description:
+// Check if this GEP's pointer argument is a GEP(Inst/ConstExpr)
+// If so check if we can merge the two GEPs into a single GEP
+//
+// Inputs:
+// GEP - A pointer to the GEP to simplify
+//
+static void simplifyGEP(GetElementPtrInst *GEP) {
+ Value *PtrOp = GEP->getOperand(0);
+ if (GEPOperator *Src = dyn_cast<GEPOperator>(PtrOp)) {
+ // Note that if our source is a gep chain itself that we wait for that
+ // chain to be resolved before we perform this transformation. This
+ // avoids us creating a TON of code in some cases.
+ //
+ if (GetElementPtrInst *SrcGEP =
+ dyn_cast<GetElementPtrInst>(Src->getOperand(0)))
+ if (SrcGEP->getNumOperands() == 2)
+ return; // Wait until our source is folded to completion.
+
+ SmallVector<Value*, 8> Indices;
+
+ // Find out whether the last index in the source GEP is a sequential idx.
+ bool EndsWithSequential = false;
+ for (gep_type_iterator I = gep_type_begin(*Src), E = gep_type_end(*Src);
+ I != E; ++I)
+ EndsWithSequential = !(*I)->isStructTy();
+
+ // Can we combine the two pointer arithmetics offsets?
+ if (EndsWithSequential) {
+ // Replace: gep (gep %P, long B), long A, ...
+ // With: T = long A+B; gep %P, T, ...
+ //
+ Value *Sum;
+ Value *SO1 = Src->getOperand(Src->getNumOperands()-1);
+ Value *GO1 = GEP->getOperand(1);
+ if (SO1 == Constant::getNullValue(SO1->getType())) {
+ Sum = GO1;
+ } else if (GO1 == Constant::getNullValue(GO1->getType())) {
+ Sum = SO1;
+ } else {
+ // If they aren't the same type, then the input hasn't been processed
+ // by the loop above yet (which canonicalizes sequential index types to
+ // intptr_t). Just avoid transforming this until the input has been
+ // normalized.
+ if (SO1->getType() != GO1->getType())
+ return;
+ Sum = llvm::BinaryOperator::Create(BinaryOperator::Add,
+ SO1, GO1,
+ PtrOp->getName()+".sum",GEP);
+ }
+
+ // Update the GEP in place if possible.
+ if (Src->getNumOperands() == 2) {
+ GEP->setOperand(0, Src->getOperand(0));
+ GEP->setOperand(1, Sum);
+ numMerged++;
+ return;
+ }
+ Indices.append(Src->op_begin()+1, Src->op_end()-1);
+ Indices.push_back(Sum);
+ Indices.append(GEP->op_begin()+2, GEP->op_end());
+ } else if (isa<Constant>(GEP->idx_begin()) &&
+ cast<Constant>(GEP->idx_begin())->isNullValue() &&
+ Src->getNumOperands() != 1) {
+ // Otherwise we can do the fold if the first index of the GEP is a zero
+ Indices.append(Src->op_begin()+1, Src->op_end());
+ Indices.append(GEP->idx_begin()+1, GEP->idx_end());
+ }
+
+ if (!Indices.empty()){
+ GetElementPtrInst *GEPNew = (GEP->isInBounds() && Src->isInBounds()) ?
+ GetElementPtrInst::CreateInBounds(Src->getOperand(0), Indices.begin(),
+ Indices.end(), GEP->getName(), GEP) :
+ GetElementPtrInst::Create(Src->getOperand(0), Indices.begin(),
+ Indices.end(), GEP->getName(), GEP);
+ numMerged++;
+ GEP->replaceAllUsesWith(GEPNew);
+ GEP->eraseFromParent();
+ }
+ }
+}
+
+// Pass ID variable
+char MergeArrayGEP::ID = 0;
+
+// Register the pass
+static RegisterPass<MergeArrayGEP>
+X("mergearrgep", "Merge GEPs for arrays indexing");
Modified: poolalloc/trunk/lib/AssistDS/SimplifyExtractValue.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/SimplifyExtractValue.cpp?rev=131006&r1=131005&r2=131006&view=diff
==============================================================================
--- poolalloc/trunk/lib/AssistDS/SimplifyExtractValue.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/SimplifyExtractValue.cpp Fri May 6 14:26:18 2011
@@ -14,9 +14,7 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "simplifyev"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
+#include "assistDS/SimplifyExtractValue.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/FormattedStream.h"
@@ -33,42 +31,76 @@
// Pass statistic
STATISTIC(numErased, "Number of Instructions Deleted");
-namespace {
- class SimplifyEV : public ModulePass {
- public:
- static char ID;
- SimplifyEV() : ModulePass(&ID) {}
- //
- // Method: runOnModule()
- //
- // Description:
- // Entry point for this LLVM pass. Search for insert/extractvalue instructions
- // that can be simplified.
- //
- // Inputs:
- // M - A reference to the LLVM module to transform.
- //
- // Outputs:
- // M - The transformed LLVM module.
- //
- // Return value:
- // true - The module was modified.
- // false - The module was not modified.
- //
- bool runOnModule(Module& M) {
- // Repeat till no change
- bool changed;
- do {
- changed = false;
- for (Module::iterator F = M.begin(); F != M.end(); ++F) {
- for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
- for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
- ExtractValueInst *EV = dyn_cast<ExtractValueInst>(I++);
- if(!EV)
- continue;
- Value *Agg = EV->getAggregateOperand();
- if (!EV->hasIndices()) {
- EV->replaceAllUsesWith(Agg);
+//
+// Method: runOnModule()
+//
+// Description:
+// Entry point for this LLVM pass. Search for insert/extractvalue instructions
+// that can be simplified.
+//
+// Inputs:
+// M - A reference to the LLVM module to transform.
+//
+// Outputs:
+// M - The transformed LLVM module.
+//
+// Return value:
+// true - The module was modified.
+// false - The module was not modified.
+//
+bool SimplifyEV::runOnModule(Module& M) {
+ // Repeat till no change
+ bool changed;
+ do {
+ changed = false;
+ for (Module::iterator F = M.begin(); F != M.end(); ++F) {
+ for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
+ for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
+ ExtractValueInst *EV = dyn_cast<ExtractValueInst>(I++);
+ if(!EV)
+ continue;
+ Value *Agg = EV->getAggregateOperand();
+ if (!EV->hasIndices()) {
+ EV->replaceAllUsesWith(Agg);
+ DEBUG(errs() << "EV:");
+ DEBUG(errs() << "ERASE:");
+ DEBUG(EV->dump());
+ EV->eraseFromParent();
+ numErased++;
+ changed = true;
+ continue;
+ }
+ if (Constant *C = dyn_cast<Constant>(Agg)) {
+ if (isa<UndefValue>(C)) {
+ EV->replaceAllUsesWith(UndefValue::get(EV->getType()));
+ DEBUG(errs() << "EV:");
+ DEBUG(errs() << "ERASE:");
+ DEBUG(EV->dump());
+ EV->eraseFromParent();
+ numErased++;
+ changed = true;
+ continue;
+ }
+ if (isa<ConstantAggregateZero>(C)) {
+ EV->replaceAllUsesWith(Constant::getNullValue(EV->getType()));
+ DEBUG(errs() << "EV:");
+ DEBUG(errs() << "ERASE:");
+ DEBUG(EV->dump());
+ EV->eraseFromParent();
+ numErased++;
+ changed = true;
+ continue;
+ }
+ if (isa<ConstantArray>(C) || isa<ConstantStruct>(C)) {
+ // Extract the element indexed by the first index out of the constant
+ Value *V = C->getOperand(*EV->idx_begin());
+ if (EV->getNumIndices() > 1) {
+ // Extract the remaining indices out of the constant indexed by the
+ // first index
+ ExtractValueInst *EV_new = ExtractValueInst::Create(V,
+ EV->idx_begin() + 1,
+ EV->idx_end(), "", EV);
+ EV->replaceAllUsesWith(EV_new);
DEBUG(errs() << "EV:");
DEBUG(errs() << "ERASE:");
DEBUG(EV->dump());
@@ -76,174 +108,133 @@
numErased++;
changed = true;
continue;
- }
- if (Constant *C = dyn_cast<Constant>(Agg)) {
- if (isa<UndefValue>(C)) {
- EV->replaceAllUsesWith(UndefValue::get(EV->getType()));
- DEBUG(errs() << "EV:");
- DEBUG(errs() << "ERASE:");
- DEBUG(EV->dump());
- EV->eraseFromParent();
- numErased++;
- changed = true;
- continue;
- }
- if (isa<ConstantAggregateZero>(C)) {
- EV->replaceAllUsesWith(Constant::getNullValue(EV->getType()));
- DEBUG(errs() << "EV:");
- DEBUG(errs() << "ERASE:");
- DEBUG(EV->dump());
- EV->eraseFromParent();
- numErased++;
- changed = true;
- continue;
- }
- if (isa<ConstantArray>(C) || isa<ConstantStruct>(C)) {
- // Extract the element indexed by the first index out of the constant
- Value *V = C->getOperand(*EV->idx_begin());
- if (EV->getNumIndices() > 1) {
- // Extract the remaining indices out of the constant indexed by the
- // first index
- ExtractValueInst *EV_new = ExtractValueInst::Create(V,
- EV->idx_begin() + 1,
- EV->idx_end(), "", EV);
- EV->replaceAllUsesWith(EV_new);
- DEBUG(errs() << "EV:");
- DEBUG(errs() << "ERASE:");
- DEBUG(EV->dump());
- EV->eraseFromParent();
- numErased++;
- changed = true;
- continue;
- } else {
- EV->replaceAllUsesWith(V);
- DEBUG(errs() << "EV:");
- DEBUG(errs() << "ERASE:");
- DEBUG(EV->dump());
- EV->eraseFromParent();
- numErased++;
- changed = true;
- continue;
- }
- }
- continue;
- }
- if (LoadInst * LI = dyn_cast<LoadInst>(Agg)) {
- SmallVector<Value*, 8> Indices;
- const Type *Int32Ty = Type::getInt32Ty(M.getContext());
- Indices.push_back(Constant::getNullValue(Int32Ty));
- for (ExtractValueInst::idx_iterator I = EV->idx_begin(), E = EV->idx_end();
- I != E; ++I) {
- Indices.push_back(ConstantInt::get(Int32Ty, *I));
- }
-
- GetElementPtrInst *GEP = GetElementPtrInst::CreateInBounds(LI->getOperand(0), Indices.begin(),
- Indices.end(), LI->getName(), LI) ;
- LoadInst *LINew = new LoadInst(GEP, "", LI);
- EV->replaceAllUsesWith(LINew);
+ } else {
+ EV->replaceAllUsesWith(V);
+ DEBUG(errs() << "EV:");
+ DEBUG(errs() << "ERASE:");
+ DEBUG(EV->dump());
EV->eraseFromParent();
- changed = true;
numErased++;
+ changed = true;
continue;
-
}
- if (InsertValueInst *IV = dyn_cast<InsertValueInst>(Agg)) {
- bool done = false;
- // We're extracting from an insertvalue instruction, compare the indices
- const unsigned *exti, *exte, *insi, *inse;
- for (exti = EV->idx_begin(), insi = IV->idx_begin(),
- exte = EV->idx_end(), inse = IV->idx_end();
- exti != exte && insi != inse;
- ++exti, ++insi) {
- if (*insi != *exti) {
- // The insert and extract both reference distinctly different elements.
- // This means the extract is not influenced by the insert, and we can
- // replace the aggregate operand of the extract with the aggregate
- // operand of the insert. i.e., replace
- // %I = insertvalue { i32, { i32 } } %A, { i32 } { i32 42 }, 1
- // %E = extractvalue { i32, { i32 } } %I, 0
- // with
- // %E = extractvalue { i32, { i32 } } %A, 0
- ExtractValueInst *EV_new = ExtractValueInst::Create(IV->getAggregateOperand(),
- EV->idx_begin(), EV->idx_end(),"", EV);
- EV->replaceAllUsesWith(EV_new);
- DEBUG(errs() << "EV:");
- DEBUG(errs() << "ERASE:");
- DEBUG(EV->dump());
- EV->eraseFromParent();
- numErased++;
- done = true;
- changed = true;
- break;
- }
- }
- if(done)
- continue;
- if (exti == exte && insi == inse) {
- // Both iterators are at the end: Index lists are identical. Replace
- // %B = insertvalue { i32, { i32 } } %A, i32 42, 1, 0
- // %C = extractvalue { i32, { i32 } } %B, 1, 0
- // with "i32 42"
- EV->replaceAllUsesWith(IV->getInsertedValueOperand());
- DEBUG(errs() << "EV:");
- DEBUG(errs() << "ERASE:");
- DEBUG(EV->dump());
- EV->eraseFromParent();
- numErased++;
- changed = true;
- continue;
-
- }
- if (exti == exte) {
- // The extract list is a prefix of the insert list. i.e. replace
- // %I = insertvalue { i32, { i32 } } %A, i32 42, 1, 0
- // %E = extractvalue { i32, { i32 } } %I, 1
- // with
- // %X = extractvalue { i32, { i32 } } %A, 1
- // %E = insertvalue { i32 } %X, i32 42, 0
- // by switching the order of the insert and extract (though the
- // insertvalue should be left in, since it may have other uses).
- Value *NewEV = ExtractValueInst::Create(IV->getAggregateOperand(),
- EV->idx_begin(), EV->idx_end(), "", EV);
- Value *NewIV = InsertValueInst::Create(NewEV, IV->getInsertedValueOperand(),
- insi, inse, "", EV);
- EV->replaceAllUsesWith(NewIV);
- DEBUG(errs() << "EV:");
- DEBUG(errs() << "ERASE:");
- DEBUG(EV->dump());
- EV->eraseFromParent();
- numErased++;
- changed = true;
- continue;
- }
- if (insi == inse) {
- // The insert list is a prefix of the extract list
- // We can simply remove the common indices from the extract and make it
- // operate on the inserted value instead of the insertvalue result.
- // i.e., replace
- // %I = insertvalue { i32, { i32 } } %A, { i32 } { i32 42 }, 1
- // %E = extractvalue { i32, { i32 } } %I, 1, 0
- // with
- // %E extractvalue { i32 } { i32 42 }, 0
- ExtractValueInst *EV_new = ExtractValueInst::Create(IV->getInsertedValueOperand(),
- exti, exte,"", EV);
- EV->replaceAllUsesWith(EV_new);
- DEBUG(errs() << "EV:");
- DEBUG(errs() << "ERASE:");
- DEBUG(EV->dump());
- EV->eraseFromParent();
- numErased++;
- changed = true;
- continue;
- }
+ }
+ continue;
+ }
+ if (LoadInst * LI = dyn_cast<LoadInst>(Agg)) {
+ SmallVector<Value*, 8> Indices;
+ const Type *Int32Ty = Type::getInt32Ty(M.getContext());
+ Indices.push_back(Constant::getNullValue(Int32Ty));
+ for (ExtractValueInst::idx_iterator I = EV->idx_begin(), E = EV->idx_end();
+ I != E; ++I) {
+ Indices.push_back(ConstantInt::get(Int32Ty, *I));
+ }
+
+ GetElementPtrInst *GEP = GetElementPtrInst::CreateInBounds(LI->getOperand(0), Indices.begin(),
+ Indices.end(), LI->getName(), LI) ;
+ LoadInst *LINew = new LoadInst(GEP, "", LI);
+ EV->replaceAllUsesWith(LINew);
+ EV->eraseFromParent();
+ changed = true;
+ numErased++;
+ continue;
+
+ }
+ if (InsertValueInst *IV = dyn_cast<InsertValueInst>(Agg)) {
+ bool done = false;
+ // We're extracting from an insertvalue instruction, compare the indices
+ const unsigned *exti, *exte, *insi, *inse;
+ for (exti = EV->idx_begin(), insi = IV->idx_begin(),
+ exte = EV->idx_end(), inse = IV->idx_end();
+ exti != exte && insi != inse;
+ ++exti, ++insi) {
+ if (*insi != *exti) {
+ // The insert and extract both reference distinctly different elements.
+ // This means the extract is not influenced by the insert, and we can
+ // replace the aggregate operand of the extract with the aggregate
+ // operand of the insert. i.e., replace
+ // %I = insertvalue { i32, { i32 } } %A, { i32 } { i32 42 }, 1
+ // %E = extractvalue { i32, { i32 } } %I, 0
+ // with
+ // %E = extractvalue { i32, { i32 } } %A, 0
+ ExtractValueInst *EV_new = ExtractValueInst::Create(IV->getAggregateOperand(),
+ EV->idx_begin(), EV->idx_end(),"", EV);
+ EV->replaceAllUsesWith(EV_new);
+ DEBUG(errs() << "EV:");
+ DEBUG(errs() << "ERASE:");
+ DEBUG(EV->dump());
+ EV->eraseFromParent();
+ numErased++;
+ done = true;
+ changed = true;
+ break;
}
}
+ if(done)
+ continue;
+ if (exti == exte && insi == inse) {
+ // Both iterators are at the end: Index lists are identical. Replace
+ // %B = insertvalue { i32, { i32 } } %A, i32 42, 1, 0
+ // %C = extractvalue { i32, { i32 } } %B, 1, 0
+ // with "i32 42"
+ EV->replaceAllUsesWith(IV->getInsertedValueOperand());
+ DEBUG(errs() << "EV:");
+ DEBUG(errs() << "ERASE:");
+ DEBUG(EV->dump());
+ EV->eraseFromParent();
+ numErased++;
+ changed = true;
+ continue;
+
+ }
+ if (exti == exte) {
+ // The extract list is a prefix of the insert list. i.e. replace
+ // %I = insertvalue { i32, { i32 } } %A, i32 42, 1, 0
+ // %E = extractvalue { i32, { i32 } } %I, 1
+ // with
+ // %X = extractvalue { i32, { i32 } } %A, 1
+ // %E = insertvalue { i32 } %X, i32 42, 0
+ // by switching the order of the insert and extract (though the
+ // insertvalue should be left in, since it may have other uses).
+ Value *NewEV = ExtractValueInst::Create(IV->getAggregateOperand(),
+ EV->idx_begin(), EV->idx_end(), "", EV);
+ Value *NewIV = InsertValueInst::Create(NewEV, IV->getInsertedValueOperand(),
+ insi, inse, "", EV);
+ EV->replaceAllUsesWith(NewIV);
+ DEBUG(errs() << "EV:");
+ DEBUG(errs() << "ERASE:");
+ DEBUG(EV->dump());
+ EV->eraseFromParent();
+ numErased++;
+ changed = true;
+ continue;
+ }
+ if (insi == inse) {
+ // The insert list is a prefix of the extract list
+ // We can simply remove the common indices from the extract and make it
+ // operate on the inserted value instead of the insertvalue result.
+ // i.e., replace
+ // %I = insertvalue { i32, { i32 } } %A, { i32 } { i32 42 }, 1
+ // %E = extractvalue { i32, { i32 } } %I, 1, 0
+ // with
+ // %E extractvalue { i32 } { i32 42 }, 0
+ ExtractValueInst *EV_new = ExtractValueInst::Create(IV->getInsertedValueOperand(),
+ exti, exte,"", EV);
+ EV->replaceAllUsesWith(EV_new);
+ DEBUG(errs() << "EV:");
+ DEBUG(errs() << "ERASE:");
+ DEBUG(EV->dump());
+ EV->eraseFromParent();
+ numErased++;
+ changed = true;
+ continue;
+ }
}
}
- } while(changed);
- return (numErased > 0);
+ }
}
- };
+ } while(changed);
+ return (numErased > 0);
}
// Pass ID variable
Modified: poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp?rev=131006&r1=131005&r2=131006&view=diff
==============================================================================
--- poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/SimplifyGEP.cpp Fri May 6 14:26:18 2011
@@ -14,10 +14,7 @@
#define DEBUG_TYPE "simplify-gep"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Instructions.h"
+#include "assistDS/SimplifyGEP.h"
#include "llvm/Constants.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/FormattedStream.h"
@@ -29,204 +26,192 @@
using namespace llvm;
-namespace {
- //
- // Method: preprocess()
- //
- // Description:
- // %p = bitcast %p1 to T1
- // gep(%p) ...
- // ->
- // gep (bitcast %p1 to T1), ...
- //
- // Inputs:
- // M - A reference to the LLVM module to process
- //
- // Outputs:
- // M - The transformed LLVM module.
- //
- static void preprocess(Module& M) {
- for (Module::iterator F = M.begin(); F != M.end(); ++F){
- for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
- for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE; I++) {
- if(!(isa<GetElementPtrInst>(I)))
- continue;
- GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
- if(BitCastInst *BI = dyn_cast<BitCastInst>(GEP->getOperand(0))) {
- if(Constant *C = dyn_cast<Constant>(BI->getOperand(0))) {
- GEP->setOperand(0, ConstantExpr::getBitCast(C, BI->getType()));
- }
+//
+// Method: preprocess()
+//
+// Description:
+// %p = bitcast %p1 to T1
+// gep(%p) ...
+// ->
+// gep (bitcast %p1 to T1), ...
+//
+// Inputs:
+// M - A reference to the LLVM module to process
+//
+// Outputs:
+// M - The transformed LLVM module.
+//
+static void preprocess(Module& M) {
+ for (Module::iterator F = M.begin(); F != M.end(); ++F){
+ for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
+ for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE; I++) {
+ if(!(isa<GetElementPtrInst>(I)))
+ continue;
+ GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
+ if(BitCastInst *BI = dyn_cast<BitCastInst>(GEP->getOperand(0))) {
+ if(Constant *C = dyn_cast<Constant>(BI->getOperand(0))) {
+ GEP->setOperand(0, ConstantExpr::getBitCast(C, BI->getType()));
}
}
}
}
}
- class SimplifyGEP : public ModulePass {
- private:
- TargetData * TD;
- public:
- static char ID;
- SimplifyGEP() : ModulePass(&ID) {}
- //
- // Method: runOnModule()
- //
- // Description:
- // Entry point for this LLVM pass.
- // Find all GEPs, and simplify them.
- //
- // Inputs:
- // M - A reference to the LLVM module to transform
- //
- // Outputs:
- // M - The transformed LLVM module.
- //
- // Return value:
- // true - The module was modified.
- // false - The module was not modified.
- //
- bool runOnModule(Module& M) {
- TD = &getAnalysis<TargetData>();
- preprocess(M);
- for (Module::iterator F = M.begin(); F != M.end(); ++F){
- for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
- for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE; I++) {
- if(!(isa<GetElementPtrInst>(I)))
- continue;
- GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
- Value *PtrOp = GEP->getOperand(0);
- Value *StrippedPtr = PtrOp->stripPointerCasts();
- // Check if the GEP base pointer is enclosed in a cast
- if (StrippedPtr != PtrOp) {
- const PointerType *StrippedPtrTy =cast<PointerType>(StrippedPtr->getType());
- bool HasZeroPointerIndex = false;
- if (ConstantInt *C = dyn_cast<ConstantInt>(GEP->getOperand(1)))
- HasZeroPointerIndex = C->isZero();
- // Transform: GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ...
- // into : GEP [10 x i8]* X, i32 0, ...
- //
- // Likewise, transform: GEP (bitcast i8* X to [0 x i8]*), i32 0, ...
- // into : GEP i8* X, ...
- //
- // This occurs when the program declares an array extern like "int X[];"
- if (HasZeroPointerIndex) {
- const PointerType *CPTy = cast<PointerType>(PtrOp->getType());
- if (const ArrayType *CATy =
- dyn_cast<ArrayType>(CPTy->getElementType())) {
- // GEP (bitcast i8* X to [0 x i8]*), i32 0, ... ?
- if (CATy->getElementType() == StrippedPtrTy->getElementType()) {
- // -> GEP i8* X, ...
- SmallVector<Value*, 8> Idx(GEP->idx_begin()+1, GEP->idx_end());
- GetElementPtrInst *Res =
- GetElementPtrInst::Create(StrippedPtr, Idx.begin(),
- Idx.end(), GEP->getName(), GEP);
- Res->setIsInBounds(GEP->isInBounds());
- GEP->replaceAllUsesWith(Res);
- continue;
- }
-
- if (const ArrayType *XATy =
- dyn_cast<ArrayType>(StrippedPtrTy->getElementType())){
- // GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ... ?
- if (CATy->getElementType() == XATy->getElementType()) {
- // -> GEP [10 x i8]* X, i32 0, ...
- // At this point, we know that the cast source type is a pointer
- // to an array of the same type as the destination pointer
- // array. Because the array type is never stepped over (there
- // is a leading zero) we can fold the cast into this GEP.
- GEP->setOperand(0, StrippedPtr);
- continue;
- }
- }
- }
- } else if (GEP->getNumOperands() == 2) {
- // Transform things like:
- // %t = getelementptr i32* bitcast ([2 x i32]* %str to i32*), i32 %V
- // into: %t1 = getelementptr [2 x i32]* %str, i32 0, i32 %V; bitcast
- const Type *SrcElTy = StrippedPtrTy->getElementType();
- const Type *ResElTy=cast<PointerType>(PtrOp->getType())->getElementType();
- if (TD && SrcElTy->isArrayTy() &&
- TD->getTypeAllocSize(cast<ArrayType>(SrcElTy)->getElementType()) ==
- TD->getTypeAllocSize(ResElTy)) {
- Value *Idx[2];
- Idx[0] = Constant::getNullValue(Type::getInt32Ty(GEP->getContext()));
- Idx[1] = GEP->getOperand(1);
- Value *NewGEP = GetElementPtrInst::Create(StrippedPtr, Idx,
- Idx+2, GEP->getName(), GEP);
- // V and GEP are both pointer types --> BitCast
- GEP->replaceAllUsesWith(new BitCastInst(NewGEP, GEP->getType(), GEP->getName(), GEP));
+}
+//
+// Method: runOnModule()
+//
+// Description:
+// Entry point for this LLVM pass.
+// Find all GEPs, and simplify them.
+//
+// Inputs:
+// M - A reference to the LLVM module to transform
+//
+// Outputs:
+// M - The transformed LLVM module.
+//
+// Return value:
+// true - The module was modified.
+// false - The module was not modified.
+//
+bool SimplifyGEP::runOnModule(Module& M) {
+ TD = &getAnalysis<TargetData>();
+ preprocess(M);
+ for (Module::iterator F = M.begin(); F != M.end(); ++F){
+ for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
+ for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE; I++) {
+ if(!(isa<GetElementPtrInst>(I)))
+ continue;
+ GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
+ Value *PtrOp = GEP->getOperand(0);
+ Value *StrippedPtr = PtrOp->stripPointerCasts();
+ // Check if the GEP base pointer is enclosed in a cast
+ if (StrippedPtr != PtrOp) {
+ const PointerType *StrippedPtrTy =cast<PointerType>(StrippedPtr->getType());
+ bool HasZeroPointerIndex = false;
+ if (ConstantInt *C = dyn_cast<ConstantInt>(GEP->getOperand(1)))
+ HasZeroPointerIndex = C->isZero();
+ // Transform: GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ...
+ // into : GEP [10 x i8]* X, i32 0, ...
+ //
+ // Likewise, transform: GEP (bitcast i8* X to [0 x i8]*), i32 0, ...
+ // into : GEP i8* X, ...
+ //
+ // This occurs when the program declares an array extern like "int X[];"
+ if (HasZeroPointerIndex) {
+ const PointerType *CPTy = cast<PointerType>(PtrOp->getType());
+ if (const ArrayType *CATy =
+ dyn_cast<ArrayType>(CPTy->getElementType())) {
+ // GEP (bitcast i8* X to [0 x i8]*), i32 0, ... ?
+ if (CATy->getElementType() == StrippedPtrTy->getElementType()) {
+ // -> GEP i8* X, ...
+ SmallVector<Value*, 8> Idx(GEP->idx_begin()+1, GEP->idx_end());
+ GetElementPtrInst *Res =
+ GetElementPtrInst::Create(StrippedPtr, Idx.begin(),
+ Idx.end(), GEP->getName(), GEP);
+ Res->setIsInBounds(GEP->isInBounds());
+ GEP->replaceAllUsesWith(Res);
+ continue;
+ }
+
+ if (const ArrayType *XATy =
+ dyn_cast<ArrayType>(StrippedPtrTy->getElementType())){
+ // GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ... ?
+ if (CATy->getElementType() == XATy->getElementType()) {
+ // -> GEP [10 x i8]* X, i32 0, ...
+ // At this point, we know that the cast source type is a pointer
+ // to an array of the same type as the destination pointer
+ // array. Because the array type is never stepped over (there
+ // is a leading zero) we can fold the cast into this GEP.
+ GEP->setOperand(0, StrippedPtr);
continue;
}
+ }
+ }
+ } else if (GEP->getNumOperands() == 2) {
+ // Transform things like:
+ // %t = getelementptr i32* bitcast ([2 x i32]* %str to i32*), i32 %V
+ // into: %t1 = getelementptr [2 x i32]* %str, i32 0, i32 %V; bitcast
+ const Type *SrcElTy = StrippedPtrTy->getElementType();
+ const Type *ResElTy=cast<PointerType>(PtrOp->getType())->getElementType();
+ if (TD && SrcElTy->isArrayTy() &&
+ TD->getTypeAllocSize(cast<ArrayType>(SrcElTy)->getElementType()) ==
+ TD->getTypeAllocSize(ResElTy)) {
+ Value *Idx[2];
+ Idx[0] = Constant::getNullValue(Type::getInt32Ty(GEP->getContext()));
+ Idx[1] = GEP->getOperand(1);
+ Value *NewGEP = GetElementPtrInst::Create(StrippedPtr, Idx,
+ Idx+2, GEP->getName(), GEP);
+ // V and GEP are both pointer types --> BitCast
+ GEP->replaceAllUsesWith(new BitCastInst(NewGEP, GEP->getType(), GEP->getName(), GEP));
+ continue;
+ }
+
+ // Transform things like:
+ // getelementptr i8* bitcast ([100 x double]* X to i8*), i32 %tmp
+ // (where tmp = 8*tmp2) into:
+ // getelementptr [100 x double]* %arr, i32 0, i32 %tmp2; bitcast
+
+ if (TD && SrcElTy->isArrayTy() && ResElTy->isIntegerTy(8)) {
+ uint64_t ArrayEltSize =
+ TD->getTypeAllocSize(cast<ArrayType>(SrcElTy)->getElementType());
+
+ // Check to see if "tmp" is a scale by a multiple of ArrayEltSize. We
+ // allow either a mul, shift, or constant here.
+ Value *NewIdx = 0;
+ ConstantInt *Scale = 0;
+ if (ArrayEltSize == 1) {
+ NewIdx = GEP->getOperand(1);
+ Scale = ConstantInt::get(cast<IntegerType>(NewIdx->getType()), 1);
+ } else if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(1))) {
+ NewIdx = ConstantInt::get(CI->getType(), 1);
+ Scale = CI;
+ } else if (Instruction *Inst =dyn_cast<Instruction>(GEP->getOperand(1))){
+ if (Inst->getOpcode() == Instruction::Shl &&
+ isa<ConstantInt>(Inst->getOperand(1))) {
+ ConstantInt *ShAmt = cast<ConstantInt>(Inst->getOperand(1));
+ uint32_t ShAmtVal = ShAmt->getLimitedValue(64);
+ Scale = ConstantInt::get(cast<IntegerType>(Inst->getType()),
+ 1ULL << ShAmtVal);
+ NewIdx = Inst->getOperand(0);
+ } else if (Inst->getOpcode() == Instruction::Mul &&
+ isa<ConstantInt>(Inst->getOperand(1))) {
+ Scale = cast<ConstantInt>(Inst->getOperand(1));
+ NewIdx = Inst->getOperand(0);
+ }
+ }
- // Transform things like:
- // getelementptr i8* bitcast ([100 x double]* X to i8*), i32 %tmp
- // (where tmp = 8*tmp2) into:
- // getelementptr [100 x double]* %arr, i32 0, i32 %tmp2; bitcast
-
- if (TD && SrcElTy->isArrayTy() && ResElTy->isIntegerTy(8)) {
- uint64_t ArrayEltSize =
- TD->getTypeAllocSize(cast<ArrayType>(SrcElTy)->getElementType());
-
- // Check to see if "tmp" is a scale by a multiple of ArrayEltSize. We
- // allow either a mul, shift, or constant here.
- Value *NewIdx = 0;
- ConstantInt *Scale = 0;
- if (ArrayEltSize == 1) {
- NewIdx = GEP->getOperand(1);
- Scale = ConstantInt::get(cast<IntegerType>(NewIdx->getType()), 1);
- } else if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(1))) {
- NewIdx = ConstantInt::get(CI->getType(), 1);
- Scale = CI;
- } else if (Instruction *Inst =dyn_cast<Instruction>(GEP->getOperand(1))){
- if (Inst->getOpcode() == Instruction::Shl &&
- isa<ConstantInt>(Inst->getOperand(1))) {
- ConstantInt *ShAmt = cast<ConstantInt>(Inst->getOperand(1));
- uint32_t ShAmtVal = ShAmt->getLimitedValue(64);
- Scale = ConstantInt::get(cast<IntegerType>(Inst->getType()),
- 1ULL << ShAmtVal);
- NewIdx = Inst->getOperand(0);
- } else if (Inst->getOpcode() == Instruction::Mul &&
- isa<ConstantInt>(Inst->getOperand(1))) {
- Scale = cast<ConstantInt>(Inst->getOperand(1));
- NewIdx = Inst->getOperand(0);
- }
- }
-
- // If the index will be to exactly the right offset with the scale taken
- // out, perform the transformation. Note, we don't know whether Scale is
- // signed or not. We'll use unsigned version of division/modulo
- // operation after making sure Scale doesn't have the sign bit set.
- if (ArrayEltSize && Scale && Scale->getSExtValue() >= 0LL &&
- Scale->getZExtValue() % ArrayEltSize == 0) {
- Scale = ConstantInt::get(Scale->getType(),
- Scale->getZExtValue() / ArrayEltSize);
- if (Scale->getZExtValue() != 1) {
- Constant *C = ConstantExpr::getIntegerCast(Scale, NewIdx->getType(),
- false /*ZExt*/);
- NewIdx = BinaryOperator::Create(BinaryOperator::Mul, NewIdx, C, "idxscale");
- }
-
- // Insert the new GEP instruction.
- Value *Idx[2];
- Idx[0] = Constant::getNullValue(Type::getInt32Ty(GEP->getContext()));
- Idx[1] = NewIdx;
- Value *NewGEP = GetElementPtrInst::Create(StrippedPtr, Idx,
- Idx+2, GEP->getName(), GEP);
- GEP->replaceAllUsesWith(new BitCastInst(NewGEP, GEP->getType(), GEP->getName(), GEP));
- continue;
- }
+ // If the index will be to exactly the right offset with the scale taken
+ // out, perform the transformation. Note, we don't know whether Scale is
+ // signed or not. We'll use unsigned version of division/modulo
+ // operation after making sure Scale doesn't have the sign bit set.
+ if (ArrayEltSize && Scale && Scale->getSExtValue() >= 0LL &&
+ Scale->getZExtValue() % ArrayEltSize == 0) {
+ Scale = ConstantInt::get(Scale->getType(),
+ Scale->getZExtValue() / ArrayEltSize);
+ if (Scale->getZExtValue() != 1) {
+ Constant *C = ConstantExpr::getIntegerCast(Scale, NewIdx->getType(),
+ false /*ZExt*/);
+ NewIdx = BinaryOperator::Create(BinaryOperator::Mul, NewIdx, C, "idxscale");
}
+
+ // Insert the new GEP instruction.
+ Value *Idx[2];
+ Idx[0] = Constant::getNullValue(Type::getInt32Ty(GEP->getContext()));
+ Idx[1] = NewIdx;
+ Value *NewGEP = GetElementPtrInst::Create(StrippedPtr, Idx,
+ Idx+2, GEP->getName(), GEP);
+ GEP->replaceAllUsesWith(new BitCastInst(NewGEP, GEP->getType(), GEP->getName(), GEP));
+ continue;
}
}
}
}
}
-
- return true;
- }
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<TargetData>();
}
- };
+ }
+
+ return true;
}
// Pass ID variable
Modified: poolalloc/trunk/lib/AssistDS/SimplifyInsertValue.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/SimplifyInsertValue.cpp?rev=131006&r1=131005&r2=131006&view=diff
==============================================================================
--- poolalloc/trunk/lib/AssistDS/SimplifyInsertValue.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/SimplifyInsertValue.cpp Fri May 6 14:26:18 2011
@@ -13,9 +13,7 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "simplify-iv"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
+#include "assistDS/SimplifyInsertValue.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/FormattedStream.h"
@@ -32,78 +30,71 @@
// Pass statistic
STATISTIC(numErased, "Number of Instructions Deleted");
-namespace {
- class SimplifyIV : public ModulePass {
- public:
- static char ID;
- SimplifyIV() : ModulePass(&ID) {}
- //
- // Method: runOnModule()
- //
- // Description:
- // Entry point for this LLVM pass. Search for insertvalue instructions
- // that can be simplified.
- //
- // Inputs:
- // M - A reference to the LLVM module to transform.
- //
- // Outputs:
- // M - The transformed LLVM module.
- //
- // Return value:
- // true - The module was modified.
- // false - The module was not modified.
- //
- bool runOnModule(Module& M) {
- // Repeat till no change
- bool changed;
- do {
- changed = false;
- std::vector<StoreInst*> worklist;
- for (Module::iterator F = M.begin(); F != M.end(); ++F) {
- for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
- for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
- InsertValueInst *IV = dyn_cast<InsertValueInst>(I++);
- if(!IV)
- continue;
- //Value *Agg = IV->getAggregateOperand();
- if(IV->getNumUses() != 1)
- continue;
- StoreInst *SI = dyn_cast<StoreInst>(IV->use_begin());
- if(!SI)
- continue;
- if(SI->getOperand(0) != IV)
- continue;
- changed = true;
- numErased++;
- do {
- SmallVector<Value*, 8> Indices;
- const Type *Int32Ty = Type::getInt32Ty(M.getContext());
- Indices.push_back(Constant::getNullValue(Int32Ty));
- for (InsertValueInst::idx_iterator I = IV->idx_begin(), E = IV->idx_end();
- I != E; ++I) {
- Indices.push_back(ConstantInt::get(Int32Ty, *I));
- }
- GetElementPtrInst *GEP = GetElementPtrInst::CreateInBounds(SI->getOperand(1), Indices.begin(),
- Indices.end(), SI->getName(), SI) ;
- new StoreInst(IV->getInsertedValueOperand(), GEP, SI);
- IV = dyn_cast<InsertValueInst>(IV->getAggregateOperand());
+//
+// Method: runOnModule()
+//
+// Description:
+// Entry point for this LLVM pass. Search for insertvalue instructions
+// that can be simplified.
+//
+// Inputs:
+// M - A reference to the LLVM module to transform.
+//
+// Outputs:
+// M - The transformed LLVM module.
+//
+// Return value:
+// true - The module was modified.
+// false - The module was not modified.
+//
+bool SimplifyIV::runOnModule(Module& M) {
+ // Repeat till no change
+ bool changed;
+ do {
+ changed = false;
+ std::vector<StoreInst*> worklist;
+ for (Module::iterator F = M.begin(); F != M.end(); ++F) {
+ for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
+ for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
+ InsertValueInst *IV = dyn_cast<InsertValueInst>(I++);
+ if(!IV)
+ continue;
+ //Value *Agg = IV->getAggregateOperand();
+ if(IV->getNumUses() != 1)
+ continue;
+ StoreInst *SI = dyn_cast<StoreInst>(IV->use_begin());
+ if(!SI)
+ continue;
+ if(SI->getOperand(0) != IV)
+ continue;
+ changed = true;
+ numErased++;
+ do {
+ SmallVector<Value*, 8> Indices;
+ const Type *Int32Ty = Type::getInt32Ty(M.getContext());
+ Indices.push_back(Constant::getNullValue(Int32Ty));
+ for (InsertValueInst::idx_iterator I = IV->idx_begin(), E = IV->idx_end();
+ I != E; ++I) {
+ Indices.push_back(ConstantInt::get(Int32Ty, *I));
+ }
+ GetElementPtrInst *GEP = GetElementPtrInst::CreateInBounds(SI->getOperand(1), Indices.begin(),
+ Indices.end(), SI->getName(), SI) ;
+ new StoreInst(IV->getInsertedValueOperand(), GEP, SI);
+ IV = dyn_cast<InsertValueInst>(IV->getAggregateOperand());
- } while(IV);
- worklist.push_back(SI);
+ } while(IV);
+ worklist.push_back(SI);
- }
- }
}
- while(!worklist.empty()) {
- StoreInst *SI = worklist.back();
- worklist.pop_back();
- SI->eraseFromParent();
- }
- } while(changed);
- return (numErased > 0);
+ }
+ }
+ while(!worklist.empty()) {
+ StoreInst *SI = worklist.back();
+ worklist.pop_back();
+ SI->eraseFromParent();
}
- };
+ } while(changed);
+ return (numErased > 0);
}
// Pass ID variable
Modified: poolalloc/trunk/lib/AssistDS/StructReturnToPointer.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/StructReturnToPointer.cpp?rev=131006&r1=131005&r2=131006&view=diff
==============================================================================
--- poolalloc/trunk/lib/AssistDS/StructReturnToPointer.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/StructReturnToPointer.cpp Fri May 6 14:26:18 2011
@@ -6,12 +6,15 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// For functions that return structures,
+// transform them to return a pointer to the structure instead.
+//
+//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "struct-ret"
-#include "llvm/Instructions.h"
+#include "assistDS/StructReturnToPointer.h"
#include "llvm/Attributes.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/FormattedStream.h"
@@ -24,121 +27,112 @@
using namespace llvm;
-namespace {
+//
+// Method: runOnModule()
+//
+// Description:
+// Entry point for this LLVM pass.
+// If a function returns a struct, make it return
+// a pointer to the struct.
+//
+// Inputs:
+// M - A reference to the LLVM module to transform
+//
+// Outputs:
+// M - The transformed LLVM module.
+//
+// Return value:
+// true - The module was modified.
+// false - The module was not modified.
+//
+bool StructRet::runOnModule(Module& M) {
+
+ std::vector<Function*> worklistR;
+ for (Module::iterator I = M.begin(); I != M.end(); ++I)
+ if (!I->isDeclaration() && !I->mayBeOverridden()) {
+ if(I->hasAddressTaken())
+ continue;
+ if(I->getReturnType()->isStructTy()) {
+ worklistR.push_back(I);
+ }
+ }
+
+ while(!worklistR.empty()) {
+ Function *F = worklistR.back();
+ worklistR.pop_back();
+ const Type *NewArgType = F->getReturnType()->getPointerTo();
+
+ // Construct the new Type
+ std::vector<const Type*>TP;
+ TP.push_back(NewArgType);
+ for (Function::arg_iterator ii = F->arg_begin(), ee = F->arg_end();
+ ii != ee; ++ii) {
+ TP.push_back(ii->getType());
+ }
+
+ const FunctionType *NFTy = FunctionType::get(F->getReturnType(), TP, F->isVarArg());
+
+ // Create the new function body and insert it into the module.
+ Function *NF = Function::Create(NFTy, F->getLinkage(), F->getName(), &M);
+ DenseMap<const Value*, Value*> ValueMap;
+ Function::arg_iterator NI = NF->arg_begin();
+ NI->setName("ret");
+ ++NI;
+ for (Function::arg_iterator II = F->arg_begin(); II != F->arg_end(); ++II, ++NI) {
+ //II->replaceAllUsesWith(NI);
+ ValueMap[II] = NI;
+ NI->setName(II->getName());
+ }
+ // Perform the cloning.
+ SmallVector<ReturnInst*,100> Returns;
+ CloneFunctionInto(NF, F, ValueMap, Returns);
+ std::vector<Value*> fargs;
+ for(Function::arg_iterator ai = NF->arg_begin(),
+ ae= NF->arg_end(); ai != ae; ++ai) {
+ fargs.push_back(ai);
+ }
+ NF->setAlignment(F->getAlignment());
+ for (Function::iterator B = NF->begin(), FE = NF->end(); B != FE; ++B) {
+ for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
+ ReturnInst * RI = dyn_cast<ReturnInst>(I++);
+ if(!RI)
+ continue;
+ new StoreInst(RI->getOperand(0), fargs.at(0), RI);
+ //ReturnInst::Create(M.getContext(), fargs, RI);
+ //RI->eraseFromParent();
+ }
+ }
- class StructArg : public ModulePass {
- public:
- static char ID;
- StructArg() : ModulePass(&ID) {}
-
- //
- // Method: runOnModule()
- //
- // Description:
- // Entry point for this LLVM pass.
- // If a function returns a struct, make it return
- // a pointer to the struct.
- //
- // Inputs:
- // M - A reference to the LLVM module to transform
- //
- // Outputs:
- // M - The transformed LLVM module.
- //
- // Return value:
- // true - The module was modified.
- // false - The module was not modified.
- //
- bool runOnModule(Module& M) {
-
- std::vector<Function*> worklistR;
- for (Module::iterator I = M.begin(); I != M.end(); ++I)
- if (!I->isDeclaration() && !I->mayBeOverridden()) {
- if(I->hasAddressTaken())
- continue;
- if(I->getReturnType()->isStructTy()) {
- worklistR.push_back(I);
- }
- }
-
- while(!worklistR.empty()) {
- Function *F = worklistR.back();
- worklistR.pop_back();
- const Type *NewArgType = F->getReturnType()->getPointerTo();
-
- // Construct the new Type
- std::vector<const Type*>TP;
- TP.push_back(NewArgType);
- for (Function::arg_iterator ii = F->arg_begin(), ee = F->arg_end();
- ii != ee; ++ii) {
- TP.push_back(ii->getType());
- }
-
- const FunctionType *NFTy = FunctionType::get(F->getReturnType(), TP, F->isVarArg());
-
- // Create the new function body and insert it into the module.
- Function *NF = Function::Create(NFTy, F->getLinkage(), F->getName(), &M);
- DenseMap<const Value*, Value*> ValueMap;
- Function::arg_iterator NI = NF->arg_begin();
- NI->setName("ret");
- ++NI;
- for (Function::arg_iterator II = F->arg_begin(); II != F->arg_end(); ++II, ++NI) {
- //II->replaceAllUsesWith(NI);
- ValueMap[II] = NI;
- NI->setName(II->getName());
- }
- // Perform the cloning.
- SmallVector<ReturnInst*,100> Returns;
- CloneFunctionInto(NF, F, ValueMap, Returns);
- std::vector<Value*> fargs;
- for(Function::arg_iterator ai = NF->arg_begin(),
- ae= NF->arg_end(); ai != ae; ++ai) {
- fargs.push_back(ai);
- }
- NF->setAlignment(F->getAlignment());
- for (Function::iterator B = NF->begin(), FE = NF->end(); B != FE; ++B) {
- for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE;) {
- ReturnInst * RI = dyn_cast<ReturnInst>(I++);
- if(!RI)
- continue;
- new StoreInst(RI->getOperand(0), fargs.at(0), RI);
- //ReturnInst::Create(M.getContext(), fargs, RI);
- //RI->eraseFromParent();
- }
- }
-
- for(Value::use_iterator ui = F->use_begin(), ue = F->use_end();
- ui != ue; ) {
- CallInst *CI = dyn_cast<CallInst>(ui++);
- if(!CI)
- continue;
- if(CI->getCalledFunction() != F)
- continue;
- if(CI->hasByValArgument())
- continue;
- AllocaInst *AllocaNew = new AllocaInst(F->getReturnType(), 0, "", CI);
- SmallVector<Value*, 8> Args;
-
- Args.push_back(AllocaNew);
- for(unsigned j =1;j<CI->getNumOperands();j++) {
- Args.push_back(CI->getOperand(j));
- }
- CallInst::Create(NF, Args.begin(), Args.end(), "", CI);
- LoadInst *LI = new LoadInst(AllocaNew, "", CI);
- CI->replaceAllUsesWith(LI);
- CI->eraseFromParent();
- }
- if(F->use_empty())
- F->eraseFromParent();
+ for(Value::use_iterator ui = F->use_begin(), ue = F->use_end();
+ ui != ue; ) {
+ CallInst *CI = dyn_cast<CallInst>(ui++);
+ if(!CI)
+ continue;
+ if(CI->getCalledFunction() != F)
+ continue;
+ if(CI->hasByValArgument())
+ continue;
+ AllocaInst *AllocaNew = new AllocaInst(F->getReturnType(), 0, "", CI);
+ SmallVector<Value*, 8> Args;
+
+ Args.push_back(AllocaNew);
+ for(unsigned j =1;j<CI->getNumOperands();j++) {
+ Args.push_back(CI->getOperand(j));
}
- return true;
+ CallInst::Create(NF, Args.begin(), Args.end(), "", CI);
+ LoadInst *LI = new LoadInst(AllocaNew, "", CI);
+ CI->replaceAllUsesWith(LI);
+ CI->eraseFromParent();
}
- };
+ if(F->use_empty())
+ F->eraseFromParent();
+ }
+ return true;
}
// Pass ID variable
-char StructArg::ID = 0;
+char StructRet::ID = 0;
// Register the pass
-static RegisterPass<StructArg>
+static RegisterPass<StructRet>
X("struct-ret", "Find struct arguments");
Modified: poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp?rev=131006&r1=131005&r2=131006&view=diff
==============================================================================
--- poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/TypeAnalysis.cpp Fri May 6 14:26:18 2011
@@ -8,10 +8,11 @@
//===----------------------------------------------------------------------===//
#include "assistDS/TypeAnalysis.h"
-#include <vector>
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Debug.h"
+#include <vector>
+
using namespace llvm;
// Pass ID variable
@@ -21,7 +22,6 @@
static RegisterPass<TypeAnalysis>
X("type-analysis", "Get types for load/stores");
-
//
// Method: runOnModule()
//
Modified: poolalloc/trunk/lib/AssistDS/VarArgsFunc.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/VarArgsFunc.cpp?rev=131006&r1=131005&r2=131006&view=diff
==============================================================================
--- poolalloc/trunk/lib/AssistDS/VarArgsFunc.cpp (original)
+++ poolalloc/trunk/lib/AssistDS/VarArgsFunc.cpp Fri May 6 14:26:18 2011
@@ -14,9 +14,7 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "varargfunc"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
+#include "assistDS/VarArgsFunc.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/FormattedStream.h"
@@ -31,107 +29,99 @@
// Pass statistics
STATISTIC(numSimplified, "Number of Calls Simplified");
-namespace {
- class VarArgsFunc : public ModulePass {
- public:
- static char ID;
- VarArgsFunc() : ModulePass(&ID) {}
-
- //
- // Method: runOnModule()
- // Description:
- // Entry point for this LLVM pass. Search for functions that are
- // unnecessarily casted to varargs type, in a CallInst.
- // Replace with direct calls to the function
- //
- // Inputs:
- // M - A reference to the LLVM module to transform.
- //
- // Outputs:
- // M - The transformed LLVM module.
- //
- // Return value:
- // true - The module was modified.
- // false - The module was not modified.
- //
- bool runOnModule(Module& M) {
- std::vector<CallInst*> worklist;
-
- for (Module::iterator I = M.begin(); I != M.end(); ++I) {
- // Go through all the functions
- if (I->mayBeOverridden())
- continue;
- //Uses of Function I
- for(Value::use_iterator ui = I->use_begin(), ue = I->use_end();
- ui != ue; ++ui)
- //Find all casted uses of the function
- if (Constant *C = dyn_cast<Constant>(ui))
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
- if (CE->getOpcode() == Instruction::BitCast)
- if(CE->getOperand(0) == I)
- if(const FunctionType *FTy = dyn_cast<FunctionType>
- ((cast<PointerType>(CE->getType()))->getElementType()))
- //casting to a varargs funtion
- if(FTy->isVarArg()) {
- // Check if bitcasted Value is used in a callInst
- for(Value::use_iterator uii = CE->use_begin(),
- uee = CE->use_end(); uii != uee; ++uii)
- if (CallInst* CI = dyn_cast<CallInst>(uii))
- if(CI->getCalledValue() == CE) {
- // add to a worklist to process
- worklist.push_back(CI);
- }
- }
+//
+// Method: runOnModule()
+// Description:
+// Entry point for this LLVM pass. Search for functions that are
+// unnecessarily casted to varargs type, in a CallInst.
+// Replace with direct calls to the function
+//
+// Inputs:
+// M - A reference to the LLVM module to transform.
+//
+// Outputs:
+// M - The transformed LLVM module.
+//
+// Return value:
+// true - The module was modified.
+// false - The module was not modified.
+//
+bool VarArgsFunc::runOnModule(Module& M) {
+ std::vector<CallInst*> worklist;
+
+ for (Module::iterator I = M.begin(); I != M.end(); ++I) {
+ // Go through all the functions
+ if (I->mayBeOverridden())
+ continue;
+ //Uses of Function I
+ for(Value::use_iterator ui = I->use_begin(), ue = I->use_end();
+ ui != ue; ++ui)
+ //Find all casted uses of the function
+ if (Constant *C = dyn_cast<Constant>(ui))
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
+ if (CE->getOpcode() == Instruction::BitCast)
+ if(CE->getOperand(0) == I)
+ if(const FunctionType *FTy = dyn_cast<FunctionType>
+ ((cast<PointerType>(CE->getType()))->getElementType()))
+ //casting to a varargs funtion
+ if(FTy->isVarArg()) {
+ // Check if bitcasted Value is used in a callInst
+ for(Value::use_iterator uii = CE->use_begin(),
+ uee = CE->use_end(); uii != uee; ++uii)
+ if (CallInst* CI = dyn_cast<CallInst>(uii))
+ if(CI->getCalledValue() == CE) {
+ // add to a worklist to process
+ worklist.push_back(CI);
+ }
+ }
+ }
+
+ // process the worklist
+ while(!worklist.empty()) {
+ CallInst *CI = worklist.back();
+ worklist.pop_back();
+ Function *F = cast<Function>(CI->getCalledValue()->stripPointerCasts());
+ // Only continue, if we are passing the exact number of arguments
+ if(F->arg_size() != (CI->getNumOperands()-1))
+ continue;
+ // Only continue if we are getting the same return type value
+ // Or we can discard the returned value.
+ if(F->getReturnType() != CI->getType()) {
+ if(!CI->use_empty())
+ continue;
+ }
+ // Check if the parameters passed match the expected types of the
+ // formal arguments
+ bool change = true;
+ unsigned arg_count = 1;
+ for (Function::arg_iterator ii = F->arg_begin(), ee = F->arg_end();ii != ee; ++ii,arg_count++) {
+ if(ii->getType() != CI->getOperand(arg_count)->getType()) {
+ change = false;
+ break;
+ }
+ }
+
+ if(change) {
+ // if we want to ignore the returned value, create a new CallInst
+ SmallVector<Value*, 8> Args;
+ for(unsigned j =1;j<CI->getNumOperands();j++) {
+ Args.push_back(CI->getOperand(j));
}
-
- // process the worklist
- while(!worklist.empty()) {
- CallInst *CI = worklist.back();
- worklist.pop_back();
- Function *F = cast<Function>(CI->getCalledValue()->stripPointerCasts());
- // Only continue, if we are passing the exact number of arguments
- if(F->arg_size() != (CI->getNumOperands()-1))
- continue;
- // Only continue if we are getting the same return type value
- // Or we can discard the returned value.
- if(F->getReturnType() != CI->getType()) {
- if(!CI->use_empty())
- continue;
- }
- // Check if the parameters passed match the expected types of the
- // formal arguments
- bool change = true;
- unsigned arg_count = 1;
- for (Function::arg_iterator ii = F->arg_begin(), ee = F->arg_end();ii != ee; ++ii,arg_count++) {
- if(ii->getType() != CI->getOperand(arg_count)->getType()) {
- change = false;
- break;
- }
- }
-
- if(change) {
- // if we want to ignore the returned value, create a new CallInst
- SmallVector<Value*, 8> Args;
- for(unsigned j =1;j<CI->getNumOperands();j++) {
- Args.push_back(CI->getOperand(j));
- }
- CallInst *CINew = CallInst::Create(F, Args.begin(), Args.end(), "", CI);
- if(F->getReturnType() == CI->getType()){ // else means no uses
- CI->replaceAllUsesWith(CINew);
- }
- DEBUG(errs() << "VA:");
- DEBUG(errs() << "ERASE:");
- DEBUG(CI->dump());
- DEBUG(errs() << "VA:");
- DEBUG(errs() << "ADDED:");
- DEBUG(CINew->dump());
- CI->eraseFromParent();
- numSimplified++;
- }
+ CallInst *CINew = CallInst::Create(F, Args.begin(), Args.end(), "", CI);
+ if(F->getReturnType() == CI->getType()){ // else means no uses
+ CI->replaceAllUsesWith(CINew);
}
- return (numSimplified > 0 );
+ DEBUG(errs() << "VA:");
+ DEBUG(errs() << "ERASE:");
+ DEBUG(CI->dump());
+ DEBUG(errs() << "VA:");
+ DEBUG(errs() << "ADDED:");
+ DEBUG(CINew->dump());
+ CI->eraseFromParent();
+ numSimplified++;
}
- };
+ }
+ return (numSimplified > 0 );
}
// Pass ID variable
More information about the llvm-commits
mailing list