[llvm-commits] [poolalloc] r129281 - /poolalloc/trunk/lib/AssistDS/StructReturnToPointer.cpp
Arushi Aggarwal
aggarwa4 at illinois.edu
Mon Apr 11 09:30:36 PDT 2011
Author: aggarwa4
Date: Mon Apr 11 11:30:36 2011
New Revision: 129281
URL: http://llvm.org/viewvc/llvm-project?rev=129281&view=rev
Log:
For functions that return structs, return a pointer
instead.
Added:
poolalloc/trunk/lib/AssistDS/StructReturnToPointer.cpp
Added: poolalloc/trunk/lib/AssistDS/StructReturnToPointer.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/AssistDS/StructReturnToPointer.cpp?rev=129281&view=auto
==============================================================================
--- poolalloc/trunk/lib/AssistDS/StructReturnToPointer.cpp (added)
+++ poolalloc/trunk/lib/AssistDS/StructReturnToPointer.cpp Mon Apr 11 11:30:36 2011
@@ -0,0 +1,140 @@
+//===-------- StructReturnToPointer.cpp ------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "struct-ret"
+
+#include "llvm/Instructions.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"
+#include "llvm/Support/Debug.h"
+
+#include <set>
+#include <map>
+#include <vector>
+
+using namespace llvm;
+
+
+namespace {
+
+ 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 *NewReturnType = F->getReturnType()->getPointerTo();
+
+ // Construct the new Type
+ std::vector<const Type*>TP;
+ 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(NewReturnType, TP, false);
+
+ // Create the new function body and insert it into the module.
+ Function *NF = Function::Create(NFTy, F->getLinkage(), F->getName(), &M);
+ NF->copyAttributesFrom(F);
+ Function::arg_iterator NI = NF->arg_begin();
+ for (Function::arg_iterator II = F->arg_begin(); II != F->arg_end(); ++II, ++NI) {
+ II->replaceAllUsesWith(NI);
+ NI->setName(II->getName());
+ }
+ NF->getBasicBlockList().splice(NF->begin(), F->getBasicBlockList());
+ Instruction *InsertPoint;
+ for (BasicBlock::iterator insrt = NF->front().begin(); isa<AllocaInst>(InsertPoint = insrt); ++insrt) {;}
+
+ Function* MallocF = M.getFunction ("malloc");
+ const Type* IntPtrT = Type::getInt64Ty(M.getContext());
+
+ const Type *BPTy = Type::getInt8PtrTy(M.getContext());
+ Value *MallocFunc = MallocF;
+ Constant *Size;
+ if (!MallocFunc) {
+ // prototype malloc as "void *malloc(size_t)"
+ Size = ConstantInt::get (IntPtrT, 123, true);
+ MallocFunc = M.getOrInsertFunction("malloc", BPTy, IntPtrT, NULL);
+ } else {
+ Size = ConstantInt::get (MallocF->arg_begin()->getType(), 123, true);
+ }
+ CallInst *MCall = CallInst::Create(MallocFunc,Size, "ret_ptr", InsertPoint);
+ Instruction *Result = new BitCastInst(MCall, NewReturnType, "", InsertPoint);
+ 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), Result, RI);
+ ReturnInst::Create(M.getContext(), Result, RI);
+ RI->eraseFromParent();
+ }
+ }
+
+ for(Value::use_iterator ui = F->use_begin(), ue = F->use_end();
+ ui != ue; ) {
+ CallInst *CI = dyn_cast<CallInst>(ui++);
+ SmallVector<Value*, 8> Args;
+ for(unsigned j =1;j<CI->getNumOperands();j++) {
+ Args.push_back(CI->getOperand(j));
+ }
+ CallInst *CINew = CallInst::Create(NF, Args.begin(), Args.end(), "", CI);
+ LoadInst *LI = new LoadInst(CINew, "", CI);
+ CI->replaceAllUsesWith(LI);
+ CI->eraseFromParent();
+ }
+ F->eraseFromParent();
+ }
+ return true;
+ }
+ };
+}
+
+// Pass ID variable
+char StructArg::ID = 0;
+
+// Register the pass
+static RegisterPass<StructArg>
+X("struct-ret", "Find struct arguments");
More information about the llvm-commits
mailing list