Added LoopIMPCachePass. This pass automatically performs IMP caching on all loops.
Microbenchmark that just sends a message that does nothing 1000000000 times in a loop goes from taking 10.2 seconds to taking 4.7 after running the pass.main
parent
289d412dac
commit
1918888ce1
@ -1 +0,0 @@
|
||||
Sun 13 Sep 2009 13:29:32 UTC
|
||||
@ -1,192 +0,0 @@
|
||||
/usr/home/theraven/llvm/lib/Transforms/GNUObjC/Debug/IvarPass.o \
|
||||
/usr/home/theraven/llvm/lib/Transforms/GNUObjC/Debug/IvarPass.d \
|
||||
/usr/home/theraven/llvm/lib/Transforms/GNUObjC/Debug/IvarPass.o: \
|
||||
IvarPass.cpp /usr/home/theraven/llvm/include/llvm/Pass.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h \
|
||||
/usr/home/theraven/llvm/include/llvm/PassSupport.h \
|
||||
/usr/home/theraven/llvm/include/llvm/PassAnalysisSupport.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/SmallVector.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/type_traits.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Function.h \
|
||||
/usr/home/theraven/llvm/include/llvm/GlobalValue.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Constant.h \
|
||||
/usr/home/theraven/llvm/include/llvm/User.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Value.h \
|
||||
/usr/home/theraven/llvm/include/llvm/AbstractTypeUser.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Use.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/Casting.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/PointerIntPair.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/PointerLikeTypeTraits.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/StringRef.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/Twine.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/StringRef.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h \
|
||||
/usr/home/theraven/llvm/include/llvm/CallingConv.h \
|
||||
/usr/home/theraven/llvm/include/llvm/BasicBlock.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Instruction.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/ilist_node.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Instruction.def \
|
||||
/usr/home/theraven/llvm/include/llvm/SymbolTableListTraits.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/ilist.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Argument.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Attributes.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/MathExtras.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Module.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Function.h \
|
||||
/usr/home/theraven/llvm/include/llvm/GlobalVariable.h \
|
||||
/usr/home/theraven/llvm/include/llvm/OperandTraits.h \
|
||||
/usr/home/theraven/llvm/include/llvm/GlobalAlias.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Metadata.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Type.h \
|
||||
/usr/home/theraven/llvm/include/llvm/LLVMContext.h \
|
||||
/usr/home/theraven/llvm/include/llvm/System/Atomic.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/GraphTraits.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/FoldingSet.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/SmallVector.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/SmallPtrSet.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/ErrorHandling.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/Compiler.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/ValueHandle.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/DenseMapInfo.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/PointerIntPair.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Value.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Instructions.h \
|
||||
/usr/home/theraven/llvm/include/llvm/InstrTypes.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Operator.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Constants.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/APInt.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/MathExtras.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/APFloat.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/APInt.h \
|
||||
/usr/home/theraven/llvm/include/llvm/DerivedTypes.h \
|
||||
/usr/home/theraven/llvm/include/llvm/GlobalAlias.h \
|
||||
/usr/home/theraven/llvm/include/llvm/GlobalVariable.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Constants.h
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Pass.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/PassSupport.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/PassAnalysisSupport.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/SmallVector.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/type_traits.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Function.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/GlobalValue.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Constant.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/User.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Value.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/AbstractTypeUser.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Use.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/Casting.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/PointerIntPair.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/PointerLikeTypeTraits.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/StringRef.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/Twine.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/StringRef.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/CallingConv.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/BasicBlock.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Instruction.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/ilist_node.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Instruction.def:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/SymbolTableListTraits.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/ilist.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Argument.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Attributes.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/MathExtras.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Module.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Function.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/GlobalVariable.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/OperandTraits.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/GlobalAlias.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Metadata.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Type.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/LLVMContext.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/System/Atomic.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/GraphTraits.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/FoldingSet.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/SmallVector.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/SmallPtrSet.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/ErrorHandling.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/Compiler.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/ValueHandle.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/DenseMapInfo.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/PointerIntPair.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Value.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Instructions.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/InstrTypes.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Operator.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Constants.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/APInt.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/MathExtras.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/APFloat.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/APInt.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/DerivedTypes.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/GlobalAlias.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/GlobalVariable.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Constants.h:
|
||||
@ -1,186 +0,0 @@
|
||||
/usr/home/theraven/llvm/lib/Transforms/GNUObjC/Debug/TypeFeedback.o \
|
||||
/usr/home/theraven/llvm/lib/Transforms/GNUObjC/Debug/TypeFeedback.d \
|
||||
/usr/home/theraven/llvm/lib/Transforms/GNUObjC/Debug/TypeFeedback.o: \
|
||||
TypeFeedback.cpp /usr/home/theraven/llvm/include/llvm/Constants.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Constant.h \
|
||||
/usr/home/theraven/llvm/include/llvm/User.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Value.h \
|
||||
/usr/home/theraven/llvm/include/llvm/AbstractTypeUser.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Use.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/Casting.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/PointerIntPair.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/PointerLikeTypeTraits.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/StringRef.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/Twine.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/StringRef.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Type.h \
|
||||
/usr/home/theraven/llvm/include/llvm/LLVMContext.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h \
|
||||
/usr/home/theraven/llvm/include/llvm/System/Atomic.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/GraphTraits.h \
|
||||
/usr/home/theraven/llvm/include/llvm/OperandTraits.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/APInt.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/MathExtras.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/APFloat.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/APInt.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/SmallVector.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/type_traits.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Pass.h \
|
||||
/usr/home/theraven/llvm/include/llvm/PassSupport.h \
|
||||
/usr/home/theraven/llvm/include/llvm/PassAnalysisSupport.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Module.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Function.h \
|
||||
/usr/home/theraven/llvm/include/llvm/GlobalValue.h \
|
||||
/usr/home/theraven/llvm/include/llvm/CallingConv.h \
|
||||
/usr/home/theraven/llvm/include/llvm/BasicBlock.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Instruction.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/ilist_node.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Instruction.def \
|
||||
/usr/home/theraven/llvm/include/llvm/SymbolTableListTraits.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/ilist.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Argument.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Attributes.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/MathExtras.h \
|
||||
/usr/home/theraven/llvm/include/llvm/GlobalVariable.h \
|
||||
/usr/home/theraven/llvm/include/llvm/GlobalAlias.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Metadata.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/FoldingSet.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/SmallVector.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/SmallPtrSet.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/ErrorHandling.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/Compiler.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Support/ValueHandle.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/DenseMapInfo.h \
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/PointerIntPair.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Value.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Function.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Instructions.h \
|
||||
/usr/home/theraven/llvm/include/llvm/InstrTypes.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Operator.h \
|
||||
/usr/home/theraven/llvm/include/llvm/Constants.h \
|
||||
/usr/home/theraven/llvm/include/llvm/DerivedTypes.h
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Constants.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Constant.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/User.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Value.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/AbstractTypeUser.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Use.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/Casting.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/PointerIntPair.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/PointerLikeTypeTraits.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/StringRef.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/Twine.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/StringRef.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Type.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/LLVMContext.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/System/Atomic.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/DataTypes.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/GraphTraits.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/OperandTraits.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/APInt.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/MathExtras.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/APFloat.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/APInt.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/SmallVector.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/type_traits.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Pass.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/PassSupport.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/PassAnalysisSupport.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Module.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Function.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/GlobalValue.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/CallingConv.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/BasicBlock.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Instruction.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/ilist_node.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Instruction.def:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/SymbolTableListTraits.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/ilist.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Argument.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Attributes.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/MathExtras.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/GlobalVariable.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/GlobalAlias.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Metadata.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/FoldingSet.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/SmallVector.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/SmallPtrSet.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/ErrorHandling.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/Compiler.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Support/ValueHandle.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/DenseMapInfo.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/ADT/PointerIntPair.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Value.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Function.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Instructions.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/InstrTypes.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Operator.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/Constants.h:
|
||||
|
||||
/usr/home/theraven/llvm/include/llvm/DerivedTypes.h:
|
||||
@ -0,0 +1,157 @@
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/GlobalAlias.h"
|
||||
#include "llvm/GlobalVariable.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Support/IRBuilder.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
||||
#include <string>
|
||||
|
||||
using namespace llvm;
|
||||
using std::string;
|
||||
|
||||
namespace
|
||||
{
|
||||
class GNULoopIMPCachePass : public FunctionPass
|
||||
{
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
GNULoopIMPCachePass() : FunctionPass((intptr_t)&ID) {}
|
||||
|
||||
Module *M;
|
||||
LLVMContext *Context;
|
||||
const PointerType *PtrTy;
|
||||
const PointerType *IdTy;
|
||||
const IntegerType *IntTy;
|
||||
|
||||
virtual bool doInitialization(Module &Mod) {
|
||||
M = &Mod;
|
||||
Context = &M->getContext();
|
||||
PtrTy = Type::getInt8PtrTy(*Context);
|
||||
// FIXME: 64-bit.
|
||||
IntTy = Type::getInt32Ty(*Context);
|
||||
IdTy = PointerType::getUnqual(PtrTy);
|
||||
return false;
|
||||
}
|
||||
virtual void getAnalysisUsage(AnalysisUsage &Info) const {
|
||||
Info.addRequired<LoopInfo>();
|
||||
}
|
||||
|
||||
|
||||
// TODO: Move this to a helper class.
|
||||
void CacheLookup(CallInst *lookup, BasicBlock *allocaBlock) {
|
||||
const Type *SlotPtrTy = lookup->getType();
|
||||
|
||||
IRBuilder<> B = IRBuilder<>(allocaBlock);
|
||||
B.SetInsertPoint(allocaBlock, allocaBlock->begin());
|
||||
Value *slot = B.CreateAlloca(SlotPtrTy, 0, "slot");
|
||||
Value *version = B.CreateAlloca(IntTy, 0, "slot_version");
|
||||
|
||||
B.SetInsertPoint(allocaBlock, allocaBlock->getTerminator());
|
||||
B.CreateStore(Constant::getNullValue(SlotPtrTy), slot);
|
||||
B.CreateStore(Constant::getNullValue(IntTy), version);
|
||||
|
||||
BasicBlock *beforeLookupBB = lookup->getParent();
|
||||
BasicBlock *lookupBB = SplitBlock(beforeLookupBB, lookup, this);
|
||||
BasicBlock::iterator iter = lookup;
|
||||
iter++;
|
||||
BasicBlock *afterLookupBB = SplitBlock(iter->getParent(), iter, this);
|
||||
|
||||
beforeLookupBB->getTerminator()->removeFromParent();
|
||||
B.SetInsertPoint(beforeLookupBB);
|
||||
// Load the slot and check that neither it nor the version is 0.
|
||||
Value *slotValue = B.CreateLoad(slot);
|
||||
Value *versionValue = B.CreateLoad(version);
|
||||
Value *receiver = lookup->getOperand(1);
|
||||
|
||||
Value *isCacheEmpty =
|
||||
B.CreateOr(versionValue, B.CreatePtrToInt(slotValue, IntTy));
|
||||
isCacheEmpty =
|
||||
B.CreateICmpEQ(isCacheEmpty, Constant::getNullValue(IntTy));
|
||||
Value *receiverNotNil =
|
||||
B.CreateICmpNE(receiver, Constant::getNullValue(receiver->getType()));
|
||||
isCacheEmpty = B.CreateAnd(isCacheEmpty, receiverNotNil);
|
||||
|
||||
BasicBlock *cacheLookupBB = BasicBlock::Create(*Context, "cache_check",
|
||||
allocaBlock->getParent());
|
||||
|
||||
B.CreateCondBr(isCacheEmpty, lookupBB, cacheLookupBB);
|
||||
|
||||
// Check the cache node is current
|
||||
B.SetInsertPoint(cacheLookupBB);
|
||||
Value *slotVersion = B.CreateStructGEP(slotValue, 3);
|
||||
// Note: Volatile load because the slot version might have changed in
|
||||
// another thread.
|
||||
slotVersion = B.CreateLoad(slotVersion, true, "slot_version");
|
||||
Value *slotCachedFor = B.CreateStructGEP(slotValue, 1);
|
||||
slotCachedFor = B.CreateLoad(slotCachedFor, true, "slot_owner");
|
||||
Value *cls = B.CreateLoad(B.CreateBitCast(receiver, IdTy));
|
||||
Value *isVersionCorrect = B.CreateICmpEQ(slotVersion, versionValue);
|
||||
Value *isOwnerCorrect = B.CreateICmpEQ(slotCachedFor, cls);
|
||||
Value *isSlotValid = B.CreateAnd(isVersionCorrect, isOwnerCorrect);
|
||||
// If this slot is still valid, skip the lookup.
|
||||
B.CreateCondBr(isSlotValid, afterLookupBB, lookupBB);
|
||||
|
||||
// Replace the looked up slot with the loaded one
|
||||
B.SetInsertPoint(afterLookupBB, afterLookupBB->begin());
|
||||
// Not volatile, so a redundant load elimination pass can do some phi
|
||||
// magic with this later.
|
||||
lookup->replaceAllUsesWith(B.CreateLoad(slot));
|
||||
|
||||
// Perform the real lookup and cache the result
|
||||
lookupBB->getTerminator()->removeFromParent();
|
||||
B.SetInsertPoint(lookupBB);
|
||||
// Store it even if the version is 0, because we always check that the
|
||||
// version is not 0 at the start and an occasional redundant store is
|
||||
// probably better than a branch every time.
|
||||
B.CreateStore(lookup, slot);
|
||||
B.CreateStore(B.CreateLoad(B.CreateStructGEP(lookup, 3)), version);
|
||||
cls = B.CreateLoad(B.CreateBitCast(receiver, IdTy));
|
||||
B.CreateStore(cls, B.CreateStructGEP(lookup, 1));
|
||||
B.CreateBr(afterLookupBB);
|
||||
}
|
||||
|
||||
virtual bool runOnFunction(Function &F) {
|
||||
LoopInfo &LI = getAnalysis<LoopInfo>();
|
||||
bool modified = false;
|
||||
SmallVector<CallInst*, 16> Lookups;
|
||||
BasicBlock *entry = &F.getEntryBlock();
|
||||
|
||||
for (Function::iterator i=F.begin(), end=F.end() ;
|
||||
i != end ; ++i) {
|
||||
// Ignore basic blocks that are not parts of loops.
|
||||
if (LI.getLoopDepth(i) == 0) { continue; }
|
||||
for (BasicBlock::iterator b=i->begin(), last=i->end() ;
|
||||
b != last ; ++b) {
|
||||
if (CallInst *call = dyn_cast<CallInst>(b)) {
|
||||
Value *callee = call->getCalledValue()->stripPointerCasts();
|
||||
if (Function *func = dyn_cast<Function>(callee)) {
|
||||
if (func->getName() == "objc_msg_lookup_sender") {
|
||||
modified = true;
|
||||
Lookups.push_back(call);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (SmallVectorImpl<CallInst*>::iterator i=Lookups.begin(),
|
||||
e=Lookups.end() ; e!=i ; i++) {
|
||||
CacheLookup(*i, entry);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
};
|
||||
|
||||
char GNULoopIMPCachePass::ID = 0;
|
||||
RegisterPass<GNULoopIMPCachePass> X("gnu-loop-imp-cache",
|
||||
"Cache IMPs in loops pass");
|
||||
}
|
||||
|
||||
FunctionPass *createGNULoopIMPCachePass(void)
|
||||
{
|
||||
return new GNULoopIMPCachePass();
|
||||
}
|
||||
Loading…
Reference in New Issue