From 91d6c8a987516b27bb9a08a352386191bf4bd9d7 Mon Sep 17 00:00:00 2001 From: Akash Kothari <akashk4@tyler.cs.illinois.edu> Date: Fri, 17 Jan 2020 12:34:07 -0600 Subject: [PATCH] Added bug fixes to DFG2LLVM_X86 pass --- .../Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp | 60 +++++++++++++++++-- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/hpvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp b/hpvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp index fb16c28c13..06e4e79183 100644 --- a/hpvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp +++ b/hpvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp @@ -827,12 +827,60 @@ void CGT_X86::codeGenLaunch(DFInternalNode* Root) { switchToTimer(visc_TimerID_COMPUTATION, CI); switchToTimer(visc_TimerID_OUTPUT_PACK, RI); - // Code for returning the output - CastInst* OutputAddrCast = CastInst::CreatePointerCast(data, - CI->getType()->getPointerTo(), - CI->getName()+".addr", - RI); - new StoreInst(CI, OutputAddrCast, RI); + StructType *RootRetTy = cast<StructType>(RootF_X86->getFunctionType()->getReturnType()); + + // if Root has non empty return + if (RootRetTy->getNumElements()) { + // We can't access the type of the arg struct - build it + std::vector<Type*> TyList; + for(Function::arg_iterator ai = RootF_X86->arg_begin(), ae = RootF_X86->arg_end(); + ai != ae; ++ai) { + TyList.push_back(ai->getType()); + } + TyList.push_back(CI->getType()); + + StructType* ArgStructTy = StructType::create(M.getContext(), + ArrayRef<Type*>(TyList), + (RootF_X86->getName()+".arg.struct.ty").str(), true); + + // Cast the data pointer to the type of the arg struct + CastInst* OutputAddrCast = CastInst::CreatePointerCast(data, + ArgStructTy->getPointerTo(), + "argStructCast.addr", + RI); + + // Result struct is the last element of the packed struct passed to launch + unsigned outStructIdx = ArgStructTy->getNumElements() - 1; + + ConstantInt *IntZero = ConstantInt::get(Type::getInt32Ty(M.getContext()), 0); + ConstantInt *IntIdx = ConstantInt::get(Type::getInt32Ty(M.getContext()), + outStructIdx); + + Value* GEPIIdxList[] = { IntZero, + IntIdx + }; + // Get data pointer to the last element of struct - result field + GetElementPtrInst *OutGEPI = + GetElementPtrInst::Create(ArgStructTy, + OutputAddrCast, + ArrayRef<Value*>(GEPIIdxList, 2), + CI->getName()+".addr", + RI); + // Store result there + new StoreInst(CI, OutGEPI, RI); + } else { + // There is no return - no need to actually code gen, but for fewer + // changes maintain what code was already doing + // We were casting the data pointer to the result type of Root, and + // returning result there. This would work at the LLVM level, but not + // at the C level, thus the rewrite. + CastInst* OutputAddrCast = CastInst::CreatePointerCast(data, + CI->getType()->getPointerTo(), + CI->getName()+".addr", + RI); + new StoreInst(CI, OutputAddrCast, RI); + } + switchToTimer(visc_TimerID_NONE, RI); DEBUG(errs() << "Application specific function:\n"); -- GitLab