Made ClassIMPCache a ModulePass (it shouldn't be a FunctionPass because it adds globals).

main
theraven 16 years ago
parent 60f87bc4ad
commit beb8356367

@ -14,61 +14,60 @@ using std::string;
namespace namespace
{ {
class ClassIMPCachePass : public FunctionPass class ClassIMPCachePass : public ModulePass
{ {
GNUstep::IMPCacher *cacher;
Module *M;
const IntegerType *IntTy; const IntegerType *IntTy;
public: public:
static char ID; static char ID;
ClassIMPCachePass() : FunctionPass((intptr_t)&ID) {} ClassIMPCachePass() : ModulePass((intptr_t)&ID) {}
~ClassIMPCachePass() { delete cacher; }
virtual bool doInitialization(Module &Mod) { virtual bool runOnModule(Module &M) {
M = &Mod; GNUstep::IMPCacher cacher = GNUstep::IMPCacher(M.getContext(), this);
cacher = new GNUstep::IMPCacher(Mod.getContext(), this);
// FIXME: ILP64 // FIXME: ILP64
IntTy = Type::getInt32Ty(Mod.getContext()); IntTy = Type::getInt32Ty(M.getContext());
return false;
}
virtual bool runOnFunction(Function &F) {
bool modified = false; bool modified = false;
SmallVector<CallInst*, 16> Lookups;
BasicBlock *entry = &F.getEntryBlock();
for (Function::iterator i=F.begin(), end=F.end() ; for (Module::iterator F=M.begin(), fend=M.end() ;
i != end ; ++i) { F != fend ; ++F) {
for (BasicBlock::iterator b=i->begin(), last=i->end() ;
b != last ; ++b) { if (F->isDeclaration()) { continue; }
if (CallInst *call = dyn_cast<CallInst>(b)) {
Value *callee = call->getCalledValue()->stripPointerCasts(); SmallVector<CallInst*, 16> Lookups;
if (Function *func = dyn_cast<Function>(callee)) { BasicBlock *entry = &F->getEntryBlock();
if (func->getName() == "objc_msg_lookup_sender") {
// TODO: Move this to a helper for (Function::iterator i=F->begin(), end=F->end() ;
Value *receiverPtr = call->getOperand(1); i != end ; ++i) {
Value *receiver = 0; for (BasicBlock::iterator b=i->begin(), last=i->end() ;
// Find where the receiver comes from b != last ; ++b) {
for (BasicBlock::iterator start=i->begin(),s=b ; s!=start ; s--) { if (CallInst *call = dyn_cast<CallInst>(b)) {
if (StoreInst *store = dyn_cast<StoreInst>(s)) { Value *callee = call->getCalledValue()->stripPointerCasts();
if (store->getOperand(1) == receiverPtr) { if (Function *func = dyn_cast<Function>(callee)) {
receiver = store->getOperand(0); if (func->getName() == "objc_msg_lookup_sender") {
break; // TODO: Move this to a helper
Value *receiverPtr = call->getOperand(1);
Value *receiver = 0;
// Find where the receiver comes from
for (BasicBlock::iterator start=i->begin(),s=b ; s!=start ; s--) {
if (StoreInst *store = dyn_cast<StoreInst>(s)) {
if (store->getOperand(1) == receiverPtr) {
receiver = store->getOperand(0);
break;
}
} }
} }
} if (0 == receiver) { continue; }
if (0 == receiver) { continue; } if (CallInst *classLookup = dyn_cast<CallInst>(receiver)) {
if (CallInst *classLookup = dyn_cast<CallInst>(receiver)) { Value *lookupVal = classLookup->getCalledValue()->stripPointerCasts();
Value *lookupVal = classLookup->getCalledValue()->stripPointerCasts(); if (Function *lookupFunc = dyn_cast<Function>(lookupVal)) {
if (Function *lookupFunc = dyn_cast<Function>(lookupVal)) { if (lookupFunc->getName() == "objc_lookup_class") {
if (lookupFunc->getName() == "objc_lookup_class") { GlobalVariable *classNameVar = cast<GlobalVariable>(
GlobalVariable *classNameVar = cast<GlobalVariable>( classLookup->getOperand(1)->stripPointerCasts());
classLookup->getOperand(1)->stripPointerCasts()); string className = cast<ConstantArray>(
string className = cast<ConstantArray>( classNameVar->getInitializer() )->getAsString();
classNameVar->getInitializer() )->getAsString(); modified = true;
modified = true; Lookups.push_back(call);
Lookups.push_back(call); }
} }
} }
} }
@ -76,19 +75,19 @@ namespace
} }
} }
} }
} IRBuilder<> B = IRBuilder<>(entry);
IRBuilder<> B = IRBuilder<>(entry); for (SmallVectorImpl<CallInst*>::iterator i=Lookups.begin(),
for (SmallVectorImpl<CallInst*>::iterator i=Lookups.begin(), e=Lookups.end() ; e!=i ; i++) {
e=Lookups.end() ; e!=i ; i++) { const Type *SlotPtrTy = (*i)->getType();
const Type *SlotPtrTy = (*i)->getType();
Value *slot = new GlobalVariable(*M, SlotPtrTy, false, Value *slot = new GlobalVariable(M, SlotPtrTy, false,
GlobalValue::PrivateLinkage, Constant::getNullValue(SlotPtrTy), GlobalValue::PrivateLinkage, Constant::getNullValue(SlotPtrTy),
"slot"); "slot");
Value *version = new GlobalVariable(*M, IntTy, false, Value *version = new GlobalVariable(M, IntTy, false,
GlobalValue::PrivateLinkage, Constant::getNullValue(IntTy), GlobalValue::PrivateLinkage, Constant::getNullValue(IntTy),
"version"); "version");
cacher->CacheLookup(*i, slot, version); cacher.CacheLookup(*i, slot, version);
}
} }
return modified; return modified;
} }
@ -99,7 +98,7 @@ namespace
"Cache IMPs for class messages"); "Cache IMPs for class messages");
} }
FunctionPass *createClassIMPCachePass(void) ModulePass *createClassIMPCachePass(void)
{ {
return new ClassIMPCachePass(); return new ClassIMPCachePass();
} }

Loading…
Cancel
Save