Index: llvm/include/llvm/Transforms/IPO/OpenMPOpt.h =================================================================== --- llvm/include/llvm/Transforms/IPO/OpenMPOpt.h +++ llvm/include/llvm/Transforms/IPO/OpenMPOpt.h @@ -175,8 +175,8 @@ bool isFilled(); }; - CallBase *RuntimeCall; /// Call that involves a memotry transfer. - InformationCache &InfoCache; + CallInst *RuntimeCall; /// Call that involves a memotry transfer. + OMPInformationCache &InfoCache; /// These help mapping the values in offload_baseptrs, offload_ptrs, and /// offload_sizes, respectively. @@ -188,7 +188,7 @@ /// RuntimeCall. SetVector Issue; - MemoryTransfer(CallBase *RuntimeCall, InformationCache &InfoCache) : + MemoryTransfer(CallInst *RuntimeCall, OMPInformationCache &InfoCache) : RuntimeCall{RuntimeCall}, InfoCache{InfoCache} {} @@ -301,6 +301,10 @@ /// moved. Returns nullptr if the movement is not possible, or not worth it. Instruction *canBeMovedUpwards(MemoryTransfer &MT); + /// Returns a pointer to the instruction where the "wait" of \p MT can be + /// moved. Returns nullptr if the movement is not possible, or not worth it. + Instruction *canBeMovedDownwards(MemoryTransfer &MT); + static Value *combinedIdentStruct(Value *CurrentIdent, Value *NextIdent, bool GlobalOnly, bool &SingleChoice); Index: llvm/lib/Transforms/IPO/OpenMPOpt.cpp =================================================================== --- llvm/lib/Transforms/IPO/OpenMPOpt.cpp +++ llvm/lib/Transforms/IPO/OpenMPOpt.cpp @@ -945,9 +945,10 @@ return false; } - if (auto *I = canBeMovedUpwards(MT)) { - // TODO: Split call and move "issue" below I. + if (canBeMovedUpwards(MT) || canBeMovedDownwards(MT)) { + // TODO: Split runtime call. } + return false; }; @@ -958,7 +959,7 @@ Instruction *OpenMPOpt::canBeMovedUpwards(MemoryTransfer &MT) { assert(MT.Issue.size() > 0 && "There's not set of instructions to be moved!"); - CallBase *RC = MT.RuntimeCall; + CallInst *RC = MT.RuntimeCall; auto *MSSAResult = OMPInfoCache.getAnalysisResultForFunction( *RC->getCaller()); @@ -978,8 +979,13 @@ continue; auto *MemInst = (cast(MemAccess))->getMemoryInst(); - if (MT.mayBeModifiedBy(MemInst)) - return MemInst; + if (MT.mayBeModifiedBy(MemInst)) { + // If MemInst is not the instruction immediately before the Issue. + if (!MT.Issue.count(MemInst->getNextNode())) + return MemInst; + + return nullptr; + } MemAccess = MSSAWalker->getClobberingMemoryAccess(MemAccess); } @@ -987,6 +993,40 @@ return nullptr; } +Instruction *OpenMPOpt::canBeMovedDownwards(MemoryTransfer &MT) { + assert(MT.Issue.size() > 0 && "There's not set of instructions to be moved!"); + + // FIXME: This traverses only the BasicBlock where MT is. Make it traverse + // the CFG. + GlobalValue *TgtTargetDecl = M.getNamedValue("__tgt_target"); + GlobalValue *TgtTargetTeamsDecl = M.getNamedValue("__tgt_target_teams"); + GlobalValue *TgtTargetDataEndDecl = M.getNamedValue("__tgt_target_data_end"); + + CallInst *RC = MT.RuntimeCall; + Instruction *Inst = RC; + bool IsWorthIt = false; + while ((Inst = Inst->getNextNode())) { + if (auto *C = dyn_cast(Inst)) { + auto *Callee = C->getCalledFunction(); + if (Callee == TgtTargetDecl || Callee == TgtTargetTeamsDecl || + Callee == TgtTargetDataEndDecl) { + if (IsWorthIt) + return Inst; + + return nullptr; + } + + // If it's a call, it is worth the movement below the call. + IsWorthIt = true; + } else if (isa(Inst)) + // If we go over a StoreInst the movement is worth it too. + IsWorthIt = true; + } + + // Return end of BasicBlock. + return &*(RC->getParent()->end()); +} + Value *OpenMPOpt::combinedIdentStruct(Value *CurrentIdent, Value *NextIdent, bool GlobalOnly, bool &SingleChoice) { if (CurrentIdent == NextIdent)