Skip to content
Snippets Groups Projects
Commit c7487643 authored by kotsifa2's avatar kotsifa2
Browse files

Modified GenVISC, intrinsics path, to replace mutateType

parent 53050a69
No related branches found
No related tags found
No related merge requests found
......@@ -939,6 +939,25 @@ bool GenVISC::runOnModule(Module &M) {
for (Module::iterator mi = M.begin(), me = M.end(); mi != me; ++mi) {
Function* f = &*mi;
DEBUG(errs() << "Function: " << f->getName() << "\n");
// Argument type list.
std::vector<Type*> FArgTypes;
for(Function::const_arg_iterator ai = f->arg_begin(), ae = f->arg_end();
ai != ae; ++ai) {
FArgTypes.push_back(ai->getType());
}
// List with the required additions in the function's return type
std::vector<Type*> FRetTypes;
enum mutateTypeCause {
mtc_None,
mtc_BIND,
mtc_RETURN,
mtc_NUM_CAUSES
} bind;
bind = mutateTypeCause::mtc_None;
// Iterate over all the instructions in this function
for (inst_iterator i = inst_begin(f), e = inst_end(f); i != e ; ++i) {
Instruction* I = &*i; // Grab pointer to Instruction
......@@ -1155,41 +1174,46 @@ bool GenVISC::runOnModule(Module &M) {
int srcpos = cast<ConstantInt>(CI->getArgOperand(1))->getSExtValue();
int destpos = cast<ConstantInt>(CI->getArgOperand(2))->getSExtValue();
StructType* ChildReturnTy = cast<StructType>(ChildF->getReturnType());
Type* ReturnType = F->getReturnType();
Type* ReturnType = F->getReturnType();
DEBUG(errs() << *ReturnType << "\n";);
assert((ReturnType->isVoidTy() || isa<StructType>(ReturnType))
&& "Return type should either be a struct or void type!");
// Get the return struct type. If void, create empty struct
StructType* ReturnStructTy;
if(ReturnType->isVoidTy())
ReturnStructTy = StructType::create(Ctx, None, Twine("struct.out."+F->getName()).str(), true);
else
ReturnStructTy = cast<StructType>(ReturnType);
std::vector<Type*> TyList;
for (unsigned i=0; i<ReturnStructTy->getNumElements(); i++)
TyList.push_back(ReturnStructTy->getElementType(i));
TyList.insert(TyList.begin()+destpos, ChildReturnTy->getElementType(srcpos));
StructType* NewReturnTy = StructType::create(Ctx, TyList, ReturnStructTy->getName(), true);
// Create the argument type list with added argument types
std::vector<Type*> ArgTypes;
for(Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
ai != ae; ++ai) {
ArgTypes.push_back(ai->getType());
}
FunctionType* FTy = FunctionType::get(NewReturnTy, ArgTypes, F->isVarArg());
PointerType* PTy = FTy->getPointerTo();
F->mutateType(PTy);
// StructType* ReturnStructTy;
// if(ReturnType->isVoidTy())
// ReturnStructTy = StructType::create(Ctx, None, Twine("struct.out."+F->getName()).str(), true);
// else
// ReturnStructTy = cast<StructType>(ReturnType);
// std::vector<Type*> TyList;
// for (unsigned i=0; i<ReturnStructTy->getNumElements(); i++)
// TyList.push_back(ReturnStructTy->getElementType(i));
// TyList.insert(TyList.begin()+destpos, ChildReturnTy->getElementType(srcpos));
// StructType* NewReturnTy = StructType::create(Ctx, TyList, ReturnStructTy->getName(), true);
// Create the argument type list with added argument types
// std::vector<Type*> ArgTypes;
// for(Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
// ai != ae; ++ai) {
// ArgTypes.push_back(ai->getType());
// }
// FunctionType* FTy = FunctionType::get(NewReturnTy, ArgTypes, F->isVarArg());
// PointerType* PTy = FTy->getPointerTo();
// F->mutateType(PTy);
// This is certainly an internal node, and hence just one BB with one
// return terminator instruction. Change return statement
ReturnInst* RI = cast<ReturnInst>(F->getEntryBlock().getTerminator());
ReturnInst* newRI = ReturnInst::Create(Ctx, UndefValue::get(NewReturnTy));
ReplaceInstWithInst(RI, newRI);
// ReturnInst* RI = cast<ReturnInst>(F->getEntryBlock().getTerminator());
// ReturnInst* newRI = ReturnInst::Create(Ctx, UndefValue::get(NewReturnTy));
// ReplaceInstWithInst(RI, newRI);
FRetTypes.insert(FRetTypes.begin()+destpos, ChildReturnTy->getElementType(srcpos));
assert(((bind == mutateTypeCause::mtc_BIND) ||
(bind == mutateTypeCause::mtc_None)) &&
"Both bind_out and visc_return detected");
bind = mutateTypeCause::mtc_BIND;
CI->replaceAllUsesWith(BindOutInst);
toBeErased.push_back(CI);
......@@ -1215,30 +1239,51 @@ bool GenVISC::runOnModule(Module &M) {
// The operands to this call are the values to be returned by the node
Value* ReturnVal = genCodeForReturn(CI);
DEBUG(errs() << *ReturnVal << "\n");
Function* F = I->getParent()->getParent();
if(F->getReturnType()->isVoidTy()) {
DEBUG(errs() << "Fixing the return type of node: " << F->getName() << "\n");
Type* ReturnType = ReturnVal->getType();
assert(isa<StructType>(ReturnType)
&& "Return type should be a struct type!");
// Function* F = I->getParent()->getParent();
// if(F->getReturnType()->isVoidTy()) {
// DEBUG(errs() << "Fixing the return type of node: " << F->getName() << "\n");
// If the return type is void, this is the first __visc__return
// instruction we have come upon. Replace the return type of the
// function with the type of this value
// Create the argument type list with added argument types
std::vector<Type*> ArgTypes;
for(Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
ai != ae; ++ai) {
ArgTypes.push_back(ai->getType());
}
// std::vector<Type*> ArgTypes;
// for(Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
// ai != ae; ++ai) {
// ArgTypes.push_back(ai->getType());
// }
FunctionType* FTy = FunctionType::get(ReturnVal->getType(), ArgTypes, F->isVarArg());
PointerType* PTy = FTy->getPointerTo();
F->mutateType(PTy);
DEBUG(errs() << "\tNew Function Type: " << *F->getType() << "\n");
// FunctionType* FTy = FunctionType::get(ReturnVal->getType(), ArgTypes, F->isVarArg());
// PointerType* PTy = FTy->getPointerTo();
// F->mutateType(PTy);
// DEBUG(errs() << "\tNew Function Type: " << *F->getType() << "\n");
// }
assert(((bind == mutateTypeCause::mtc_RETURN) ||
(bind == mutateTypeCause::mtc_None)) &&
"Both bind_out and visc_return detected");
if (bind == mutateTypeCause::mtc_None) {
// If this is None, this is the first __visc__return
// instruction we have come upon. Place the return type of the
// function in the return type vector
bind = mutateTypeCause::mtc_RETURN;
StructType* ReturnStructTy = cast<StructType>(ReturnType);
for (unsigned i = 0; i < ReturnStructTy->getNumElements(); i++)
FRetTypes.push_back(ReturnStructTy->getElementType(i));
} else { // bind == mutateTypeCause::mtc_RETURN
// This is not the first __visc__return
// instruction we have come upon.
// Check that the return types are the same
assert((ReturnType == FRetTypes[0])
&& "Multiple returns with mismatching types");
}
assert(ReturnVal->getType() == F->getReturnType()
&& "Multiple returns with mismatching types");
ReturnInst* RetInst = ReturnInst::Create(Ctx, ReturnVal);
DEBUG(errs() << "Found visc return call: " << *CI << "\n");
Instruction* oldReturn = CI->getParent()->getTerminator();
......@@ -1249,6 +1294,7 @@ bool GenVISC::runOnModule(Module &M) {
//CI->replaceAllUsesWith(RetInst);
toBeErased.push_back(CI);
ReplaceInstWithInst(oldReturn, RetInst);
}
if (isVISCCall_getNodeInstanceID_x(I)) {
......@@ -1324,6 +1370,54 @@ bool GenVISC::runOnModule(Module &M) {
ReplaceCallWithIntrinsic(I, Intrinsic::cos, &toBeErased);
}
}
Type* ReturnType = f->getReturnType();
DEBUG(errs() << *ReturnType << "\n";);
assert((ReturnType->isVoidTy() || isa<StructType>(ReturnType))
&& "Return type should either be a struct or void type!");
// Get the return struct type. If void, create empty struct
StructType* ReturnStructTy;
if(ReturnType->isVoidTy())
ReturnStructTy = StructType::create(f->getContext(), None, Twine("struct.out."+f->getName()).str(), true);
else
ReturnStructTy = cast<StructType>(ReturnType);
std::vector<Type*> TyList;
for (unsigned i = 0; i < ReturnStructTy->getNumElements(); i++)
TyList.push_back(ReturnStructTy->getElementType(i));
for (unsigned i = 0; i < FRetTypes.size(); i++)
TyList.push_back(FRetTypes[i]);
StructType* NewReturnTy = StructType::create(f->getContext(), TyList, ReturnStructTy->getName(), true);
FunctionType* FTy = FunctionType::get(NewReturnTy, FArgTypes, f->isVarArg());
// Change the function type
SmallVector<ReturnInst*, 8> FReturns;
Function* newF = cloneFunction(f, FTy, true, &FReturns);
DEBUG(errs() << *newF << "\n");
// Replace ret void instruction with ret %RetTy undef
for(auto RI: FReturns) {
DEBUG(errs() << "Found return inst: "<< *RI << "\n");
ReturnInst* newRI = ReturnInst::Create(newF->getContext(),
UndefValue::get(NewReturnTy));
ReplaceInstWithInst(RI, newRI);
}
if (bind == mutateTypeCause::mtc_BIND) {
// This is certainly an internal node, and hence just one BB with one
// return terminator instruction. Change return statement
ReturnInst* RI = cast<ReturnInst>(f->getEntryBlock().getTerminator());
ReturnInst* newRI = ReturnInst::Create(newF->getContext(), UndefValue::get(NewReturnTy));
ReplaceInstWithInst(RI, newRI);
}
if (bind == mutateTypeCause::mtc_RETURN) {
// Nothing
}
replaceNodeFunctionInIR(*f->getParent(), f, newF);
// Erase the __visc__node calls
errs() << "Erase " << toBeErased.size() << " Statements:\n";
for(auto I: toBeErased) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment