-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Refactor Loop TapirTarget / Add GPU Backend #73
base: master
Are you sure you want to change the base?
Changes from 2 commits
845ed63
6b516f5
a1d105c
f386baa
e5ab01b
88238ab
66d5c31
eb90d5c
73db2e4
ce4802c
37605e1
34a8631
56dbd31
36dde8a
40c8a97
8a53a3d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
/** | ||
*************************************************************************** | ||
* Copyright (c) 2017, Los Alamos National Security, LLC. | ||
* All rights reserved. | ||
* | ||
* Copyright 2010. Los Alamos National Security, LLC. This software was | ||
* produced under U.S. Government contract DE-AC52-06NA25396 for Los | ||
* Alamos National Laboratory (LANL), which is operated by Los Alamos | ||
* National Security, LLC for the U.S. Department of Energy. The | ||
* U.S. Government has rights to use, reproduce, and distribute this | ||
* software. NEITHER THE GOVERNMENT NOR LOS ALAMOS NATIONAL SECURITY, | ||
* LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY | ||
* FOR THE USE OF THIS SOFTWARE. If software is modified to produce | ||
* derivative works, such modified software should be clearly marked, | ||
* so as not to confuse it with the version available from LANL. | ||
* | ||
* Additionally, redistribution and use in source and binary forms, | ||
* with or without modification, are permitted provided that the | ||
* following conditions are met: | ||
* | ||
* * Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* | ||
* * Redistributions in binary form must reproduce the above | ||
* copyright notice, this list of conditions and the following | ||
* disclaimer in the documentation and/or other materials provided | ||
* with the distribution. | ||
* | ||
* * Neither the name of Los Alamos National Security, LLC, Los | ||
* Alamos National Laboratory, LANL, the U.S. Government, nor the | ||
* names of its contributors may be used to endorse or promote | ||
* products derived from this software without specific prior | ||
* written permission. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY LOS ALAMOS NATIONAL SECURITY, LLC AND | ||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, | ||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
* DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL SECURITY, LLC OR | ||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | ||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
* SUCH DAMAGE. | ||
* | ||
***************************************************************************/ | ||
|
||
#ifndef PTX_ABI_H_ | ||
#define PTX_ABI_H_ | ||
|
||
#include "llvm/Transforms/Scalar.h" | ||
#include "llvm/ADT/SmallPtrSet.h" | ||
#include "llvm/ADT/SmallVector.h" | ||
#include "llvm/ADT/Statistic.h" | ||
#include "llvm/Analysis/AssumptionCache.h" | ||
#include "llvm/IR/Constants.h" | ||
#include "llvm/IR/Dominators.h" | ||
#include "llvm/IR/Function.h" | ||
#include "llvm/IR/InlineAsm.h" | ||
#include "llvm/IR/InstIterator.h" | ||
#include "llvm/IR/Instructions.h" | ||
#include "llvm/IR/Intrinsics.h" | ||
#include "llvm/IR/IRBuilder.h" | ||
#include "llvm/IR/Module.h" | ||
#include "llvm/IR/TypeBuilder.h" | ||
#include "llvm/IR/ValueSymbolTable.h" | ||
#include "llvm/Support/Debug.h" | ||
#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h" | ||
#include "llvm/Transforms/Utils/BasicBlockUtils.h" | ||
#include "llvm/Transforms/Utils/Cloning.h" | ||
#include "llvm/Transforms/Utils/ValueMapper.h" | ||
#include "llvm/Transforms/Tapir/LoopSpawning.h" | ||
#include "llvm/Transforms/Tapir/TapirUtils.h" | ||
#include <deque> | ||
|
||
namespace llvm { | ||
|
||
/// PTXABILoopSpawning uses the Cilk Plus ABI to handle Tapir loops. | ||
class PTXABILoopSpawning : public LoopOutline { | ||
public: | ||
PTXABILoopSpawning(Loop *OrigLoop, ScalarEvolution &SE, | ||
LoopInfo *LI, DominatorTree *DT, | ||
AssumptionCache *AC, | ||
OptimizationRemarkEmitter &ORE) | ||
: LoopOutline(OrigLoop, SE, LI, DT, AC, ORE) | ||
{} | ||
|
||
bool processLoop(); | ||
|
||
virtual ~PTXABILoopSpawning() {} | ||
|
||
protected: | ||
|
||
// private: | ||
// /// Report an analysis message to assist the user in diagnosing loops that are | ||
// /// not transformed. These are handled as LoopAccessReport rather than | ||
// /// VectorizationReport because the << operator of LoopSpawningReport returns | ||
// /// LoopAccessReport. | ||
// void emitAnalysis(const LoopAccessReport &Message) const { | ||
// emitAnalysisDiag(OrigLoop, *ORE, Message); | ||
// } | ||
private: | ||
uint32_t nextKernelId_ = 0; | ||
}; | ||
|
||
class PTXABI : public TapirTarget { | ||
public: | ||
PTXABI(); | ||
Value *GetOrCreateWorker8(Function &F) override final; | ||
void createSync(SyncInst &inst, ValueToValueMapTy &DetachCtxToStackFrame) | ||
override final; | ||
|
||
Function *createDetach(DetachInst &Detach, | ||
ValueToValueMapTy &DetachCtxToStackFrame, | ||
DominatorTree &DT, AssumptionCache &AC) override final; | ||
void preProcessFunction(Function &F) override final; | ||
void postProcessFunction(Function &F) override final; | ||
void postProcessHelper(Function &F) override final; | ||
bool processMain(Function &F) override final; | ||
|
||
}; | ||
|
||
} // end of llvm namespace | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,6 +46,7 @@ | |
#include "llvm/Transforms/Scalar/LoopDeletion.h" | ||
#include "llvm/Transforms/Tapir.h" | ||
#include "llvm/Transforms/Tapir/Outline.h" | ||
#include "llvm/Transforms/Tapir/PTXABI.h" | ||
#include "llvm/Transforms/Tapir/TapirUtils.h" | ||
#include "llvm/Transforms/Utils/PromoteMemToReg.h" | ||
#include "llvm/Transforms/Utils/LoopUtils.h" | ||
|
@@ -75,7 +76,9 @@ static cl::opt<TapirTargetType> ClTapirTarget( | |
clEnumValN(TapirTargetType::OpenMP, | ||
"openmp", "OpenMP"), | ||
clEnumValN(TapirTargetType::Qthreads, | ||
"qthreads", "Qthreads"))); | ||
"qthreads", "Qthreads"), | ||
clEnumValN(TapirTargetType::PTX, | ||
"ptx", "PTX"))); | ||
|
||
namespace { | ||
// /// \brief This modifies LoopAccessReport to initialize message with | ||
|
@@ -115,6 +118,13 @@ static void emitMissedWarning(Function *F, Loop *L, | |
<< "Tapir loop not transformed: " | ||
<< "failed to use divide-and-conquer loop spawning"); | ||
break; | ||
case LoopSpawningHints::ST_GPU: | ||
ORE->emit(DiagnosticInfoOptimizationFailure( | ||
DEBUG_TYPE, "FailedRequestedSpawning", | ||
L->getStartLoc(), L->getHeader()) | ||
<< "Tapir loop not transformed: " | ||
<< "failed to use GPU loop spawning"); | ||
break; | ||
case LoopSpawningHints::ST_SEQ: | ||
ORE->emit(DiagnosticInfoOptimizationFailure( | ||
DEBUG_TYPE, "SpawningDisabled", | ||
|
@@ -1417,6 +1427,35 @@ bool LoopSpawningImpl::processLoop(Loop *L) { | |
case LoopSpawningHints::ST_SEQ: | ||
DEBUG(dbgs() << "LS: Hints dictate sequential spawning.\n"); | ||
break; | ||
case LoopSpawningHints::ST_GPU: | ||
DEBUG(dbgs() << "LS: Hints dictate DAC spawning.\n"); | ||
{ | ||
DebugLoc DLoc = L->getStartLoc(); | ||
BasicBlock *Header = L->getHeader(); | ||
PTXABILoopSpawning DLS(L, SE, &LI, &DT, &AC, ORE); | ||
// CilkABILoopSpawning DLS(L, SE, &LI, &DT, &AC, ORE); | ||
// DACLoopSpawning DLS(L, SE, LI, DT, TLI, TTI, ORE); | ||
if (DLS.processLoop()) { | ||
DEBUG({ | ||
if (verifyFunction(*L->getHeader()->getParent())) { | ||
dbgs() << "Transformed function is invalid.\n"; | ||
return false; | ||
} | ||
}); | ||
// Report success. | ||
ORE.emit(OptimizationRemark(LS_NAME, "DACSpawning", DLoc, Header) | ||
<< "spawning iterations using divide-and-conquer"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line looks like it reports the wrong message. |
||
return true; | ||
} else { | ||
// Report failure. | ||
ORE.emit(OptimizationRemarkMissed(LS_NAME, "NoDACSpawning", DLoc, | ||
Header) | ||
<< "cannot spawn iterations using divide-and-conquer"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line looks like it reports the wrong message. |
||
emitMissedWarning(F, L, Hints, &ORE); | ||
return false; | ||
} | ||
} | ||
break; | ||
case LoopSpawningHints::ST_DAC: | ||
DEBUG(dbgs() << "LS: Hints dictate DAC spawning.\n"); | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -488,19 +488,19 @@ Function* formatFunctionToTask(Function* extracted, CallInst* cal) { | |
IRBuilder<> CallerIRBuilder(cal); | ||
auto *SharedsTySize = | ||
CallerIRBuilder.getInt64(DL.getTypeAllocSize(SharedsTy)); | ||
auto *KmpTaskTTy = createKmpTaskTTy(C); | ||
//unused -- auto *KmpTaskTTy = createKmpTaskTTy(C); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we just delete this line and the other |
||
auto *KmpTaskTWithPrivatesTy = createKmpTaskTWithPrivatesTy(SharedsTy);//KmpTaskTTy); | ||
auto *KmpTaskTWithPrivatesPtrTy = | ||
PointerType::getUnqual(KmpTaskTWithPrivatesTy); | ||
auto *KmpTaskTWithPrivatesTySize = | ||
CallerIRBuilder.getInt64(DL.getTypeAllocSize(KmpTaskTWithPrivatesTy)); | ||
|
||
auto *VoidTy = Type::getVoidTy(C); | ||
auto *Int8PtrTy = Type::getInt8PtrTy(C); | ||
// unused -- auto *Int8PtrTy = Type::getInt8PtrTy(C); | ||
auto *Int32Ty = Type::getInt32Ty(C); | ||
|
||
auto *CopyFnTy = FunctionType::get(VoidTy, {Int8PtrTy}, true); | ||
auto *CopyFnPtrTy = PointerType::getUnqual(CopyFnTy); | ||
// unused -- auto *CopyFnTy = FunctionType::get(VoidTy, {Int8PtrTy}, true); | ||
// unused -- auto *CopyFnPtrTy = PointerType::getUnqual(CopyFnTy); | ||
|
||
auto *OutlinedFnTy = FunctionType::get( | ||
VoidTy, | ||
|
@@ -593,12 +593,12 @@ Function *llvm::OpenMPABI::createDetach(DetachInst &detach, | |
ValueToValueMapTy &DetachCtxToStackFrame, | ||
DominatorTree &DT, AssumptionCache &AC) { | ||
BasicBlock *detB = detach.getParent(); | ||
Function &F = *(detB->getParent()); | ||
// unused -- Function &F = *(detB->getParent()); | ||
|
||
BasicBlock *Spawned = detach.getDetached(); | ||
BasicBlock *Continue = detach.getContinue(); | ||
|
||
Module *M = F.getParent(); | ||
// unused -- Module *M = F.getParent(); | ||
|
||
CallInst *cal = nullptr; | ||
Function *extracted = extractDetachBodyToFunction(detach, DT, AC, &cal); | ||
|
@@ -676,7 +676,7 @@ void llvm::OpenMPABI::postProcessFunction(Function &F) { | |
} | ||
} | ||
|
||
for(int i=1; i<VisitedVec.size(); i++) { | ||
for(unsigned int i=1; i<VisitedVec.size(); i++) { | ||
for (auto P : predecessors(VisitedVec[i])) { | ||
if (Visited.count(P) == 0) { | ||
std::swap(VisitedVec[0], VisitedVec[i]); | ||
|
@@ -803,6 +803,8 @@ void llvm::OpenMPABI::postProcessFunction(Function &F) { | |
OpenMPRuntimeFunction::OMPRTL__kmpc_fork_call, F.getParent()); | ||
// Replace the old call with __kmpc_fork_call | ||
auto *ForkCall = emitRuntimeCall(ForkRTFn, OMPRegionFnArgs, "", b); | ||
assert(ForkCall != 0); // play it safe -- something better to do here? | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm being nit-picky, but for matching code style, I think we would write |
||
ExtractedFnCI->eraseFromParent(); | ||
RegionFn->eraseFromParent(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This debug statement will print the wrong message.