From 07032ca7715e479974d7da4b07d717ca17689ab1 Mon Sep 17 00:00:00 2001 From: Prakalp Srivastava <prakalps@gmail.com> Date: Sun, 3 May 2015 14:14:17 -0500 Subject: [PATCH] (1) Added timer support for DFG2LLVM_X86 pass. New timers for calcualting pthread creation overhead added --- llvm/include/llvm/SupportVISC/VISCTimer.h | 7 ++ .../Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp | 68 +++++++++++++++++-- llvm/projects/visc-rt/visc-rt.cpp | 5 +- llvm/test/VISC/parboil/common/mk/visc.mk | 2 +- 4 files changed, 73 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/SupportVISC/VISCTimer.h b/llvm/include/llvm/SupportVISC/VISCTimer.h index e1fb2762f3..9151049914 100644 --- a/llvm/include/llvm/SupportVISC/VISCTimer.h +++ b/llvm/include/llvm/SupportVISC/VISCTimer.h @@ -86,6 +86,7 @@ enum visc_TimerID { visc_TimerID_OVERLAP, /* Time double-counted in asynchronous and * host activity: automatically filled in, * not intended for direct usage */ + // GPU FUNCTION visc_TimerID_INIT_CTX, visc_TimerID_CLEAR_CTX, visc_TimerID_COPY_SCALAR, @@ -96,6 +97,12 @@ enum visc_TimerID { visc_TimerID_MEM_TRACK, visc_TimerID_MEM_UNTRACK, visc_TimerID_MISC, + // LAUNCH FUNCTION + visc_TimerID_PTHREAD_CREATE, + visc_TimerID_ARG_UNPACK, + visc_TimerID_COMPUTATION, + visc_TimerID_OUTPUT_PACK, + visc_TimerID_OUTPUT_UNPACK, visc_TimerID_LAST /* Number of timer IDs */ }; diff --git a/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp b/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp index 88c9a1ee3d..bd6aa65aa1 100644 --- a/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp +++ b/llvm/lib/Transforms/DFG2LLVM_X86/DFG2LLVM_X86.cpp @@ -78,6 +78,8 @@ private: Constant* llvm_visc_switchToTimer; Constant* llvm_visc_printTimerSet; + GlobalVariable* TimerSet; + //Functions void initRuntimeAPI(); std::vector<IntrinsicInst*>* getWaitList(Value* LI); @@ -185,6 +187,36 @@ void CodeGenTraversal::initRuntimeAPI() { runtimeModule->getFunction("llvm_visc_x86_wait")->getFunctionType()); DEBUG(errs() << *llvm_visc_x86_wait); + llvm_visc_initializeTimerSet = M.getOrInsertFunction("llvm_visc_initializeTimerSet", + runtimeModule->getFunction("llvm_visc_initializeTimerSet")->getFunctionType()); + DEBUG(errs() << *llvm_visc_initializeTimerSet); + + llvm_visc_switchToTimer = M.getOrInsertFunction("llvm_visc_switchToTimer", + runtimeModule->getFunction("llvm_visc_switchToTimer")->getFunctionType()); + DEBUG(errs() << *llvm_visc_switchToTimer); + + llvm_visc_printTimerSet = M.getOrInsertFunction("llvm_visc_printTimerSet", + runtimeModule->getFunction("llvm_visc_printTimerSet")->getFunctionType()); + DEBUG(errs() << *llvm_visc_printTimerSet); + + // Insert init timer in main + for (Module::iterator mi = M.begin(), me = M.end(); mi != me; ++mi) { + Function* f = &*mi; + errs() << "Function: " << f->getName() << "\n"; + if(f->getName().equals("main")) { + DEBUG(errs() << "Initializing context" << "\n"); + for(inst_iterator i = inst_begin(f), e = inst_end(f); i != e; ++i) { + //if(Label) + } + errs() << "First instruction: " << *inst_begin(f) << "\n"; + Instruction* I = &*inst_begin(f); + initializeTimerSet(I); + switchToTimer(visc_TimerID_NONE, I); + } + } + + + } /* Returns vector of all wait instructions @@ -313,12 +345,13 @@ Value* CodeGenTraversal::addLoop(Instruction* I, Value* limit, const Twine& inde } void CodeGenTraversal::codeGenLaunch(DFInternalNode* Root) { - // TODO: Place an assert to check if the constant passed bu launch intrinsic + // TODO: Place an assert to check if the constant passed by launch intrinsic // as the number of arguments to DFG is same as the number of arguments of the // root of DFG DEBUG(errs() << "Generating Launch Function\n"); // Get Launch Instruction IntrinsicInst* LI = Root->getInstruction(); + switchToTimer(visc_TimerID_PTHREAD_CREATE, LI); DEBUG(errs() << "Generating Launch Function\n"); /* Now we have all the necessary global declarations necessary to generate the @@ -351,6 +384,7 @@ void CodeGenTraversal::codeGenLaunch(DFInternalNode* Root) { ReturnInst* RI = ReturnInst::Create(AppFunc->getContext(), Constant::getNullValue(AppFunc->getReturnType()), BB); + switchToTimer(visc_TimerID_ARG_UNPACK, RI); DEBUG(errs() << "Created Empty Launch Function\n"); // Find the X86 function generated for Root and @@ -391,6 +425,9 @@ void CodeGenTraversal::codeGenLaunch(DFInternalNode* Root) { argNum++; data = GEP; } + // Add timers around Call to RootF_X86 function + switchToTimer(visc_TimerID_COMPUTATION, CI); + switchToTimer(visc_TimerID_OUTPUT_PACK, RI); // Code for returning the output CastInst* OutputAddrCast = CastInst::CreatePointerCast(data, @@ -398,6 +435,7 @@ void CodeGenTraversal::codeGenLaunch(DFInternalNode* Root) { CI->getName()+".addr", RI); new StoreInst(CI, OutputAddrCast, RI); + switchToTimer(visc_TimerID_NONE, RI); DEBUG(errs() << "Application specific function:\n"); DEBUG(errs() << *AppFunc << "\n"); @@ -420,6 +458,7 @@ void CodeGenTraversal::codeGenLaunch(DFInternalNode* Root) { ArrayRef<Value*>(LaunchInst), ""); ReplaceInstWithInst(waitI, waitI_X86); + printTimerSet(waitI_X86->getNextNode()); DEBUG(errs() << *waitI_X86 << "\n"); } @@ -832,22 +871,37 @@ void CodeGenTraversal::codeGen(DFLeafNode* N) { } void CodeGenTraversal::initializeTimerSet(Instruction* InsertBefore) { - TIMER(CallInst::Create(llvm_visc_initializeTimerSet, - None, - "", - InsertBefore)); + Value* TimerSetAddr; + StoreInst* SI; + TIMER(TimerSet = new GlobalVariable(M, + Type::getInt8PtrTy(M.getContext()), + false, + GlobalValue::CommonLinkage, + Constant::getNullValue(Type::getInt8PtrTy(M.getContext())), + "viscTimerSet_X86")); + DEBUG(errs() << "Inserting GV: " << *TimerSet->getType() << *TimerSet << "\n"); + DEBUG(errs() << "Inserting call to: " << *llvm_visc_initializeTimerSet << "\n"); + + TIMER(TimerSetAddr = CallInst::Create(llvm_visc_initializeTimerSet, + None, + "", + InsertBefore)); + DEBUG(errs() << "TimerSetAddress = " << *TimerSetAddr << "\n"); + TIMER(SI = new StoreInst(TimerSetAddr, TimerSet, InsertBefore)); + DEBUG(errs() << "Store Timer Address in Global variable: " << *SI << "\n"); } void CodeGenTraversal::switchToTimer(enum visc_TimerID timer, Instruction* InsertBefore) { + Value* switchArgs[] = {TimerSet, getTimerID(M, timer)}; TIMER(CallInst::Create(llvm_visc_switchToTimer, - ArrayRef<Value*>(getTimerID(M, timer)), + ArrayRef<Value*>(switchArgs, 2), "", InsertBefore)); } void CodeGenTraversal::printTimerSet(Instruction* InsertBefore) { TIMER(CallInst::Create(llvm_visc_printTimerSet, - None, + ArrayRef<Value*>(TimerSet), "", InsertBefore)); } diff --git a/llvm/projects/visc-rt/visc-rt.cpp b/llvm/projects/visc-rt/visc-rt.cpp index de348979bf..27ab2b0238 100644 --- a/llvm/projects/visc-rt/visc-rt.cpp +++ b/llvm/projects/visc-rt/visc-rt.cpp @@ -804,7 +804,8 @@ visc_PrintTimerSet(struct visc_TimerSet *timers) const char *categories[] = { "IO", "Kernel", "Copy", "Driver", "Copy Async", "Compute", "Overlap", "Init_Ctx", "Clear_Ctx", "Copy_Scalar", "Copy_Ptr", "Mem_Free", - "Read_Output", "Setup", "Mem_Track", "Mem_Untrack", "Misc" + "Read_Output", "Setup", "Mem_Track", "Mem_Untrack", "Misc", + "Pthread_Create", "Arg_Unpack", "Computation", "Output_Pack", "Output_Unpack" }; @@ -1184,7 +1185,9 @@ void llvm_visc_switchToTimer(void** timerSet, enum visc_TimerID timer) { visc_SwitchToTimer((visc_TimerSet*)(*timerSet), timer); } void llvm_visc_printTimerSet(void** timerSet) { + cout<< "Entered Print timer set\n"; visc_PrintTimerSet((visc_TimerSet*) (*timerSet)); + cout<< "Exiting Print timer set\n"; } void* llvm_visc_initializeTimerSet() { diff --git a/llvm/test/VISC/parboil/common/mk/visc.mk b/llvm/test/VISC/parboil/common/mk/visc.mk index a6c54b943e..68532ef623 100644 --- a/llvm/test/VISC/parboil/common/mk/visc.mk +++ b/llvm/test/VISC/parboil/common/mk/visc.mk @@ -23,7 +23,7 @@ VISC_OPTFLAGS = -load LLVMBuildDFG.so -load LLVMDFG2LLVM_NVPTX.so -load LLVMDFG2 HOST_LINKFLAGS = ifeq ($(NO_TIMER),) - VISC_OPTFLAGS+=-visc-timers + VISC_OPTFLAGS+=-visc-timers-x86 -visc-timers-ptx endif -- GitLab