mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 12:56:06 +00:00
[MLIR][OpenMP] Refactoring createTargetData in OMPIRBuilder
Key changes: - Refactor the createTargetData function to make use of the emitOffloadingArrays and emitOffloadingArraysArgument functions to generate code. - Added a new emitIfClause helper function to allow handling if clauses in a similar fashion to Clang. - Updated the MLIR side of code to account for changes to createTargetData. Depends on D149872 Reviewed By: jdoerfert Differential Revision: https://reviews.llvm.org/D146557
This commit is contained in:
parent
7e229217f4
commit
a032dc139d
@ -1478,6 +1478,25 @@ public:
|
||||
/// Computes the size of type in bytes.
|
||||
Value *getSizeInBytes(Value *BasePtr);
|
||||
|
||||
// Emit a branch from the current block to the Target block only if
|
||||
// the current block has a terminator.
|
||||
void emitBranch(BasicBlock *Target);
|
||||
|
||||
// If BB has no use then delete it and return. Else place BB after the current
|
||||
// block, if possible, or else at the end of the function. Also add a branch
|
||||
// from current block to BB if current block does not have a terminator.
|
||||
void emitBlock(BasicBlock *BB, Function *CurFn, bool IsFinished = false);
|
||||
|
||||
/// Emits code for OpenMP 'if' clause using specified \a BodyGenCallbackTy
|
||||
/// Here is the logic:
|
||||
/// if (Cond) {
|
||||
/// ThenGen();
|
||||
/// } else {
|
||||
/// ElseGen();
|
||||
/// }
|
||||
void emitIfClause(Value *Cond, BodyGenCallbackTy ThenGen,
|
||||
BodyGenCallbackTy ElseGen, InsertPointTy AllocaIP = {});
|
||||
|
||||
/// Create the global variable holding the offload mappings information.
|
||||
GlobalVariable *createOffloadMaptypes(SmallVectorImpl<uint64_t> &Mappings,
|
||||
std::string VarName);
|
||||
@ -1987,29 +2006,41 @@ public:
|
||||
StringRef EntryFnName,
|
||||
StringRef EntryFnIDName,
|
||||
int32_t NumTeams, int32_t NumThreads);
|
||||
/// Type of BodyGen to use for region codegen
|
||||
///
|
||||
/// Priv: If device pointer privatization is required, emit the body of the
|
||||
/// region here. It will have to be duplicated: with and without
|
||||
/// privatization.
|
||||
/// DupNoPriv: If we need device pointer privatization, we need
|
||||
/// to emit the body of the region with no privatization in the 'else' branch
|
||||
/// of the conditional.
|
||||
/// NoPriv: If we don't require privatization of device
|
||||
/// pointers, we emit the body in between the runtime calls. This avoids
|
||||
/// duplicating the body code.
|
||||
enum BodyGenTy { Priv, DupNoPriv, NoPriv };
|
||||
|
||||
/// Generator for '#omp target data'
|
||||
///
|
||||
/// \param Loc The location where the target data construct was encountered.
|
||||
/// \param AllocaIP The insertion points to be used for alloca instructions.
|
||||
/// \param CodeGenIP The insertion point at which the target directive code
|
||||
/// should be placed.
|
||||
/// \param MapTypeFlags BitVector storing the mapType flags for the
|
||||
/// mapOperands.
|
||||
/// \param MapNames Names for the mapOperands.
|
||||
/// \param MapperAllocas Pointers to the AllocInsts for the map clause.
|
||||
/// \param IsBegin If true then emits begin mapper call otherwise emits
|
||||
/// end mapper call.
|
||||
/// \param DeviceID Stores the DeviceID from the device clause.
|
||||
/// \param IfCond Value which corresponds to the if clause condition.
|
||||
/// \param ProcessMapOpCB Callback that generates code for the map clause.
|
||||
/// \param BodyGenCB Callback that will generate the region code.
|
||||
/// \param Info Stores all information realted to the Target Data directive.
|
||||
/// \param GenMapInfoCB Callback that populates the MapInfos and returns.
|
||||
/// \param BodyGenCB Optional Callback to generate the region code.
|
||||
OpenMPIRBuilder::InsertPointTy createTargetData(
|
||||
const LocationDescription &Loc, OpenMPIRBuilder::InsertPointTy CodeGenIP,
|
||||
SmallVectorImpl<uint64_t> &MapTypeFlags,
|
||||
SmallVectorImpl<Constant *> &MapNames,
|
||||
struct MapperAllocas &MapperAllocas, bool IsBegin, int64_t DeviceID,
|
||||
Value *IfCond, BodyGenCallbackTy ProcessMapOpCB,
|
||||
BodyGenCallbackTy BodyGenCB = {});
|
||||
const LocationDescription &Loc, InsertPointTy AllocaIP,
|
||||
InsertPointTy CodeGenIP, Value *DeviceID, Value *IfCond,
|
||||
TargetDataInfo &Info,
|
||||
function_ref<MapInfosTy &(InsertPointTy CodeGenIP)> GenMapInfoCB,
|
||||
omp::RuntimeFunction *MapperFunc = nullptr,
|
||||
function_ref<InsertPointTy(InsertPointTy CodeGenIP,
|
||||
BodyGenTy BodyGenType)>
|
||||
BodyGenCB = nullptr);
|
||||
|
||||
using TargetBodyGenCallbackTy = function_ref<InsertPointTy(
|
||||
InsertPointTy AllocaIP, InsertPointTy CodeGenIP)>;
|
||||
|
@ -4078,73 +4078,121 @@ Constant *OpenMPIRBuilder::registerTargetRegionFunction(
|
||||
}
|
||||
|
||||
OpenMPIRBuilder::InsertPointTy OpenMPIRBuilder::createTargetData(
|
||||
const LocationDescription &Loc, OpenMPIRBuilder::InsertPointTy CodeGenIP,
|
||||
SmallVectorImpl<uint64_t> &MapTypeFlags,
|
||||
SmallVectorImpl<Constant *> &MapNames, struct MapperAllocas &MapperAllocas,
|
||||
bool IsBegin, int64_t DeviceID, Value *IfCond,
|
||||
BodyGenCallbackTy ProcessMapOpCB, BodyGenCallbackTy BodyGenCB) {
|
||||
const LocationDescription &Loc, InsertPointTy AllocaIP,
|
||||
InsertPointTy CodeGenIP, Value *DeviceID, Value *IfCond,
|
||||
TargetDataInfo &Info,
|
||||
function_ref<MapInfosTy &(InsertPointTy CodeGenIP)> GenMapInfoCB,
|
||||
omp::RuntimeFunction *MapperFunc,
|
||||
function_ref<InsertPointTy(InsertPointTy CodeGenIP, BodyGenTy BodyGenType)>
|
||||
BodyGenCB) {
|
||||
if (!updateToLocation(Loc))
|
||||
return InsertPointTy();
|
||||
|
||||
Builder.restoreIP(CodeGenIP);
|
||||
bool IsStandAlone = !BodyGenCB;
|
||||
|
||||
// LLVM utilities like blocks with terminators.
|
||||
// The UI acts as a resume point for code insertion after the BodyGen
|
||||
auto *UI = Builder.CreateUnreachable();
|
||||
if (IfCond) {
|
||||
auto *ThenTI =
|
||||
SplitBlockAndInsertIfThen(IfCond, UI, /* Unreachable */ false);
|
||||
ThenTI->getParent()->setName("omp_if.then");
|
||||
Builder.SetInsertPoint(ThenTI);
|
||||
} else {
|
||||
Builder.SetInsertPoint(UI);
|
||||
}
|
||||
// Generate the code for the opening of the data environment. Capture all the
|
||||
// arguments of the runtime call by reference because they are used in the
|
||||
// closing of the region.
|
||||
auto BeginThenGen = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) {
|
||||
emitOffloadingArrays(AllocaIP, Builder.saveIP(),
|
||||
GenMapInfoCB(Builder.saveIP()), Info,
|
||||
/*IsNonContiguous=*/true);
|
||||
|
||||
ProcessMapOpCB(Builder.saveIP(), Builder.saveIP());
|
||||
TargetDataRTArgs RTArgs;
|
||||
emitOffloadingArraysArgument(Builder, RTArgs, Info);
|
||||
|
||||
uint32_t SrcLocStrSize;
|
||||
Constant *SrcLocStr = getOrCreateSrcLocStr(Loc, SrcLocStrSize);
|
||||
Value *srcLocInfo = getOrCreateIdent(SrcLocStr, SrcLocStrSize);
|
||||
// Emit the number of elements in the offloading arrays.
|
||||
Value *PointerNum = Builder.getInt32(Info.NumberOfPtrs);
|
||||
|
||||
GlobalVariable *MapTypesGV =
|
||||
createOffloadMaptypes(MapTypeFlags, ".offload_maptypes");
|
||||
Value *MapTypesArg = Builder.CreateConstInBoundsGEP2_32(
|
||||
ArrayType::get(Builder.getInt64Ty(), MapTypeFlags.size()), MapTypesGV,
|
||||
/*Idx0=*/0, /*Idx1=*/0);
|
||||
// Source location for the ident struct
|
||||
uint32_t SrcLocStrSize;
|
||||
Constant *SrcLocStr = getOrCreateSrcLocStr(Loc, SrcLocStrSize);
|
||||
Value *SrcLocInfo = getOrCreateIdent(SrcLocStr, SrcLocStrSize);
|
||||
|
||||
GlobalVariable *MapNamesGV =
|
||||
createOffloadMapnames(MapNames, ".offload_mapnames");
|
||||
Value *MapNamesArg = Builder.CreateConstInBoundsGEP2_32(
|
||||
ArrayType::get(Builder.getInt8PtrTy(), MapNames.size()), MapNamesGV,
|
||||
/*Idx0=*/0, /*Idx1=*/0);
|
||||
Value *OffloadingArgs[] = {SrcLocInfo, DeviceID,
|
||||
PointerNum, RTArgs.BasePointersArray,
|
||||
RTArgs.PointersArray, RTArgs.SizesArray,
|
||||
RTArgs.MapTypesArray, RTArgs.MapNamesArray,
|
||||
RTArgs.MappersArray};
|
||||
|
||||
Function *beginMapperFunc =
|
||||
getOrCreateRuntimeFunctionPtr(omp::OMPRTL___tgt_target_data_begin_mapper);
|
||||
Function *endMapperFunc =
|
||||
getOrCreateRuntimeFunctionPtr(omp::OMPRTL___tgt_target_data_end_mapper);
|
||||
if (IsStandAlone) {
|
||||
assert(MapperFunc && "MapperFunc missing for standalone target data");
|
||||
Builder.CreateCall(getOrCreateRuntimeFunctionPtr(*MapperFunc),
|
||||
OffloadingArgs);
|
||||
} else {
|
||||
Function *BeginMapperFunc = getOrCreateRuntimeFunctionPtr(
|
||||
omp::OMPRTL___tgt_target_data_begin_mapper);
|
||||
|
||||
Builder.CreateCall(BeginMapperFunc, OffloadingArgs);
|
||||
|
||||
// If device pointer privatization is required, emit the body of the
|
||||
// region here. It will have to be duplicated: with and without
|
||||
// privatization.
|
||||
Builder.restoreIP(BodyGenCB(Builder.saveIP(), BodyGenTy::Priv));
|
||||
}
|
||||
};
|
||||
|
||||
// If we need device pointer privatization, we need to emit the body of the
|
||||
// region with no privatization in the 'else' branch of the conditional.
|
||||
// Otherwise, we don't have to do anything.
|
||||
auto BeginElseGen = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) {
|
||||
Builder.restoreIP(BodyGenCB(Builder.saveIP(), BodyGenTy::DupNoPriv));
|
||||
};
|
||||
|
||||
// Generate code for the closing of the data region.
|
||||
auto EndThenGen = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) {
|
||||
TargetDataRTArgs RTArgs;
|
||||
emitOffloadingArraysArgument(Builder, RTArgs, Info, /*EmitDebug=*/false,
|
||||
/*ForEndCall=*/true);
|
||||
|
||||
// Emit the number of elements in the offloading arrays.
|
||||
Value *PointerNum = Builder.getInt32(Info.NumberOfPtrs);
|
||||
|
||||
// Source location for the ident struct
|
||||
uint32_t SrcLocStrSize;
|
||||
Constant *SrcLocStr = getOrCreateSrcLocStr(Loc, SrcLocStrSize);
|
||||
Value *SrcLocInfo = getOrCreateIdent(SrcLocStr, SrcLocStrSize);
|
||||
|
||||
Value *OffloadingArgs[] = {SrcLocInfo, DeviceID,
|
||||
PointerNum, RTArgs.BasePointersArray,
|
||||
RTArgs.PointersArray, RTArgs.SizesArray,
|
||||
RTArgs.MapTypesArray, RTArgs.MapNamesArray,
|
||||
RTArgs.MappersArray};
|
||||
Function *EndMapperFunc =
|
||||
getOrCreateRuntimeFunctionPtr(omp::OMPRTL___tgt_target_data_end_mapper);
|
||||
|
||||
Builder.CreateCall(EndMapperFunc, OffloadingArgs);
|
||||
};
|
||||
|
||||
// We don't have to do anything to close the region if the if clause evaluates
|
||||
// to false.
|
||||
auto EndElseGen = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) {};
|
||||
|
||||
if (BodyGenCB) {
|
||||
// Create call to start the data region.
|
||||
emitMapperCall(Builder.saveIP(), beginMapperFunc, srcLocInfo, MapTypesArg,
|
||||
MapNamesArg, MapperAllocas, DeviceID, MapTypeFlags.size());
|
||||
if (IfCond) {
|
||||
emitIfClause(IfCond, BeginThenGen, BeginElseGen, AllocaIP);
|
||||
} else {
|
||||
BeginThenGen(AllocaIP, Builder.saveIP());
|
||||
}
|
||||
|
||||
BodyGenCB(Builder.saveIP(), Builder.saveIP());
|
||||
// If we don't require privatization of device pointers, we emit the body in
|
||||
// between the runtime calls. This avoids duplicating the body code.
|
||||
Builder.restoreIP(BodyGenCB(Builder.saveIP(), BodyGenTy::NoPriv));
|
||||
|
||||
Builder.SetInsertPoint(UI->getParent());
|
||||
// Create call to end the data region.
|
||||
emitMapperCall(Builder.saveIP(), endMapperFunc, srcLocInfo, MapTypesArg,
|
||||
MapNamesArg, MapperAllocas, DeviceID, MapTypeFlags.size());
|
||||
if (IfCond) {
|
||||
emitIfClause(IfCond, EndThenGen, EndElseGen, AllocaIP);
|
||||
} else {
|
||||
EndThenGen(AllocaIP, Builder.saveIP());
|
||||
}
|
||||
} else {
|
||||
emitMapperCall(Builder.saveIP(), IsBegin ? beginMapperFunc : endMapperFunc,
|
||||
srcLocInfo, MapTypesArg, MapNamesArg, MapperAllocas,
|
||||
DeviceID, MapTypeFlags.size());
|
||||
if (IfCond) {
|
||||
emitIfClause(IfCond, BeginThenGen, EndElseGen, AllocaIP);
|
||||
} else {
|
||||
BeginThenGen(AllocaIP, Builder.saveIP());
|
||||
}
|
||||
}
|
||||
|
||||
// Update the insertion point and remove the terminator we introduced.
|
||||
Builder.SetInsertPoint(UI->getParent());
|
||||
if (IfCond)
|
||||
UI->getParent()->setName("omp_if.end");
|
||||
UI->eraseFromParent();
|
||||
return Builder.saveIP();
|
||||
}
|
||||
|
||||
@ -4668,6 +4716,77 @@ void OpenMPIRBuilder::emitOffloadingArrays(
|
||||
emitNonContiguousDescriptor(AllocaIP, CodeGenIP, CombinedInfo, Info);
|
||||
}
|
||||
|
||||
void OpenMPIRBuilder::emitBranch(BasicBlock *Target) {
|
||||
BasicBlock *CurBB = Builder.GetInsertBlock();
|
||||
|
||||
if (!CurBB || CurBB->getTerminator()) {
|
||||
// If there is no insert point or the previous block is already
|
||||
// terminated, don't touch it.
|
||||
} else {
|
||||
// Otherwise, create a fall-through branch.
|
||||
Builder.CreateBr(Target);
|
||||
}
|
||||
|
||||
Builder.ClearInsertionPoint();
|
||||
}
|
||||
|
||||
void OpenMPIRBuilder::emitBlock(BasicBlock *BB, Function *CurFn,
|
||||
bool IsFinished) {
|
||||
BasicBlock *CurBB = Builder.GetInsertBlock();
|
||||
|
||||
// Fall out of the current block (if necessary).
|
||||
emitBranch(BB);
|
||||
|
||||
if (IsFinished && BB->use_empty()) {
|
||||
BB->eraseFromParent();
|
||||
return;
|
||||
}
|
||||
|
||||
// Place the block after the current block, if possible, or else at
|
||||
// the end of the function.
|
||||
if (CurBB && CurBB->getParent())
|
||||
CurFn->insert(std::next(CurBB->getIterator()), BB);
|
||||
else
|
||||
CurFn->insert(CurFn->end(), BB);
|
||||
Builder.SetInsertPoint(BB);
|
||||
}
|
||||
|
||||
void OpenMPIRBuilder::emitIfClause(Value *Cond, BodyGenCallbackTy ThenGen,
|
||||
BodyGenCallbackTy ElseGen,
|
||||
InsertPointTy AllocaIP) {
|
||||
// If the condition constant folds and can be elided, try to avoid emitting
|
||||
// the condition and the dead arm of the if/else.
|
||||
if (auto *CI = dyn_cast<ConstantInt>(Cond)) {
|
||||
auto CondConstant = CI->getSExtValue();
|
||||
if (CondConstant)
|
||||
ThenGen(AllocaIP, Builder.saveIP());
|
||||
else
|
||||
ElseGen(AllocaIP, Builder.saveIP());
|
||||
return;
|
||||
}
|
||||
|
||||
Function *CurFn = Builder.GetInsertBlock()->getParent();
|
||||
|
||||
// Otherwise, the condition did not fold, or we couldn't elide it. Just
|
||||
// emit the conditional branch.
|
||||
BasicBlock *ThenBlock = BasicBlock::Create(M.getContext(), "omp_if.then");
|
||||
BasicBlock *ElseBlock = BasicBlock::Create(M.getContext(), "omp_if.else");
|
||||
BasicBlock *ContBlock = BasicBlock::Create(M.getContext(), "omp_if.end");
|
||||
Builder.CreateCondBr(Cond, ThenBlock, ElseBlock);
|
||||
// Emit the 'then' code.
|
||||
emitBlock(ThenBlock, CurFn);
|
||||
ThenGen(AllocaIP, Builder.saveIP());
|
||||
emitBranch(ContBlock);
|
||||
// Emit the 'else' code if present.
|
||||
// There is no need to emit line number for unconditional branch.
|
||||
emitBlock(ElseBlock, CurFn);
|
||||
ElseGen(AllocaIP, Builder.saveIP());
|
||||
// There is no need to emit line number for unconditional branch.
|
||||
emitBranch(ContBlock);
|
||||
// Emit the continuation block for code after the if.
|
||||
emitBlock(ContBlock, CurFn, /*IsFinished=*/true);
|
||||
}
|
||||
|
||||
bool OpenMPIRBuilder::checkAndEmitFlushAfterAtomic(
|
||||
const LocationDescription &Loc, llvm::AtomicOrdering AO, AtomicKind AK) {
|
||||
assert(!(AO == AtomicOrdering::NotAtomic ||
|
||||
|
@ -4886,18 +4886,9 @@ TEST_F(OpenMPIRBuilderTest, TargetEnterData) {
|
||||
OMPBuilder.initialize();
|
||||
F->setName("func");
|
||||
IRBuilder<> Builder(BB);
|
||||
|
||||
OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
|
||||
|
||||
unsigned NumDataOperands = 1;
|
||||
int64_t DeviceID = 2;
|
||||
struct OpenMPIRBuilder::MapperAllocas MapperAllocas;
|
||||
SmallVector<uint64_t> MapTypeFlagsTo = {1};
|
||||
SmallVector<Constant *> MapNames;
|
||||
auto *I8PtrTy = Builder.getInt8PtrTy();
|
||||
auto *ArrI8PtrTy = ArrayType::get(I8PtrTy, NumDataOperands);
|
||||
auto *I64Ty = Builder.getInt64Ty();
|
||||
auto *ArrI64Ty = ArrayType::get(I64Ty, NumDataOperands);
|
||||
|
||||
AllocaInst *Val1 =
|
||||
Builder.CreateAlloca(Builder.getInt32Ty(), Builder.getInt64(1));
|
||||
@ -4905,44 +4896,34 @@ TEST_F(OpenMPIRBuilderTest, TargetEnterData) {
|
||||
|
||||
IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(),
|
||||
F->getEntryBlock().getFirstInsertionPt());
|
||||
OMPBuilder.createMapperAllocas(Builder.saveIP(), AllocaIP, NumDataOperands,
|
||||
MapperAllocas);
|
||||
|
||||
llvm::OpenMPIRBuilder::MapInfosTy CombinedInfo;
|
||||
using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
|
||||
auto ProcessMapOpCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) {
|
||||
Value *DataValue = Val1;
|
||||
Value *DataPtrBase;
|
||||
Value *DataPtr;
|
||||
DataPtrBase = DataValue;
|
||||
DataPtr = DataValue;
|
||||
Builder.restoreIP(CodeGenIP);
|
||||
auto GenMapInfoCB =
|
||||
[&](InsertPointTy codeGenIP) -> llvm::OpenMPIRBuilder::MapInfosTy & {
|
||||
// Get map clause information.
|
||||
Builder.restoreIP(codeGenIP);
|
||||
|
||||
Value *Null = Constant::getNullValue(DataValue->getType()->getPointerTo());
|
||||
Value *SizeGep =
|
||||
Builder.CreateGEP(DataValue->getType(), Null, Builder.getInt32(1));
|
||||
Value *SizePtrToInt = Builder.CreatePtrToInt(SizeGep, I64Ty);
|
||||
|
||||
Value *PtrBaseGEP =
|
||||
Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.ArgsBase,
|
||||
{Builder.getInt32(0), Builder.getInt32(0)});
|
||||
Value *PtrBaseCast = Builder.CreateBitCast(
|
||||
PtrBaseGEP, DataPtrBase->getType()->getPointerTo());
|
||||
Builder.CreateStore(DataPtrBase, PtrBaseCast);
|
||||
Value *PtrGEP =
|
||||
Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.Args,
|
||||
{Builder.getInt32(0), Builder.getInt32(0)});
|
||||
Value *PtrCast =
|
||||
Builder.CreateBitCast(PtrGEP, DataPtr->getType()->getPointerTo());
|
||||
Builder.CreateStore(DataPtr, PtrCast);
|
||||
Value *SizeGEP =
|
||||
Builder.CreateInBoundsGEP(ArrI64Ty, MapperAllocas.ArgSizes,
|
||||
{Builder.getInt32(0), Builder.getInt32(0)});
|
||||
Builder.CreateStore(SizePtrToInt, SizeGEP);
|
||||
CombinedInfo.BasePointers.emplace_back(Val1);
|
||||
CombinedInfo.Pointers.emplace_back(Val1);
|
||||
CombinedInfo.Sizes.emplace_back(Builder.getInt64(4));
|
||||
CombinedInfo.Types.emplace_back(llvm::omp::OpenMPOffloadMappingFlags(1));
|
||||
uint32_t temp;
|
||||
CombinedInfo.Names.emplace_back(
|
||||
OMPBuilder.getOrCreateSrcLocStr("unknown", temp));
|
||||
return CombinedInfo;
|
||||
};
|
||||
|
||||
llvm::OpenMPIRBuilder::TargetDataInfo Info(
|
||||
/*RequiresDevicePointerInfo=*/false,
|
||||
/*SeparateBeginEndCalls=*/true);
|
||||
|
||||
OMPBuilder.Config.setIsTargetCodegen(true);
|
||||
|
||||
llvm::omp::RuntimeFunction RTLFunc = OMPRTL___tgt_target_data_begin_mapper;
|
||||
Builder.restoreIP(OMPBuilder.createTargetData(
|
||||
Loc, Builder.saveIP(), MapTypeFlagsTo, MapNames, MapperAllocas,
|
||||
/* IsBegin= */ true, DeviceID, /* IfCond= */ nullptr, ProcessMapOpCB));
|
||||
Loc, AllocaIP, Builder.saveIP(), Builder.getInt64(DeviceID),
|
||||
/* IfCond= */ nullptr, Info, GenMapInfoCB, &RTLFunc));
|
||||
|
||||
CallInst *TargetDataCall = dyn_cast<CallInst>(&BB->back());
|
||||
EXPECT_NE(TargetDataCall, nullptr);
|
||||
@ -4962,18 +4943,9 @@ TEST_F(OpenMPIRBuilderTest, TargetExitData) {
|
||||
OMPBuilder.initialize();
|
||||
F->setName("func");
|
||||
IRBuilder<> Builder(BB);
|
||||
|
||||
OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
|
||||
|
||||
unsigned NumDataOperands = 1;
|
||||
int64_t DeviceID = 2;
|
||||
struct OpenMPIRBuilder::MapperAllocas MapperAllocas;
|
||||
SmallVector<uint64_t> MapTypeFlagsFrom = {2};
|
||||
SmallVector<Constant *> MapNames;
|
||||
auto *I8PtrTy = Builder.getInt8PtrTy();
|
||||
auto *ArrI8PtrTy = ArrayType::get(I8PtrTy, NumDataOperands);
|
||||
auto *I64Ty = Builder.getInt64Ty();
|
||||
auto *ArrI64Ty = ArrayType::get(I64Ty, NumDataOperands);
|
||||
|
||||
AllocaInst *Val1 =
|
||||
Builder.CreateAlloca(Builder.getInt32Ty(), Builder.getInt64(1));
|
||||
@ -4981,44 +4953,34 @@ TEST_F(OpenMPIRBuilderTest, TargetExitData) {
|
||||
|
||||
IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(),
|
||||
F->getEntryBlock().getFirstInsertionPt());
|
||||
OMPBuilder.createMapperAllocas(Builder.saveIP(), AllocaIP, NumDataOperands,
|
||||
MapperAllocas);
|
||||
|
||||
llvm::OpenMPIRBuilder::MapInfosTy CombinedInfo;
|
||||
using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
|
||||
auto ProcessMapOpCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) {
|
||||
Value *DataValue = Val1;
|
||||
Value *DataPtrBase;
|
||||
Value *DataPtr;
|
||||
DataPtrBase = DataValue;
|
||||
DataPtr = DataValue;
|
||||
Builder.restoreIP(CodeGenIP);
|
||||
auto GenMapInfoCB =
|
||||
[&](InsertPointTy codeGenIP) -> llvm::OpenMPIRBuilder::MapInfosTy & {
|
||||
// Get map clause information.
|
||||
Builder.restoreIP(codeGenIP);
|
||||
|
||||
Value *Null = Constant::getNullValue(DataValue->getType()->getPointerTo());
|
||||
Value *SizeGep =
|
||||
Builder.CreateGEP(DataValue->getType(), Null, Builder.getInt32(1));
|
||||
Value *SizePtrToInt = Builder.CreatePtrToInt(SizeGep, I64Ty);
|
||||
|
||||
Value *PtrBaseGEP =
|
||||
Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.ArgsBase,
|
||||
{Builder.getInt32(0), Builder.getInt32(0)});
|
||||
Value *PtrBaseCast = Builder.CreateBitCast(
|
||||
PtrBaseGEP, DataPtrBase->getType()->getPointerTo());
|
||||
Builder.CreateStore(DataPtrBase, PtrBaseCast);
|
||||
Value *PtrGEP =
|
||||
Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.Args,
|
||||
{Builder.getInt32(0), Builder.getInt32(0)});
|
||||
Value *PtrCast =
|
||||
Builder.CreateBitCast(PtrGEP, DataPtr->getType()->getPointerTo());
|
||||
Builder.CreateStore(DataPtr, PtrCast);
|
||||
Value *SizeGEP =
|
||||
Builder.CreateInBoundsGEP(ArrI64Ty, MapperAllocas.ArgSizes,
|
||||
{Builder.getInt32(0), Builder.getInt32(0)});
|
||||
Builder.CreateStore(SizePtrToInt, SizeGEP);
|
||||
CombinedInfo.BasePointers.emplace_back(Val1);
|
||||
CombinedInfo.Pointers.emplace_back(Val1);
|
||||
CombinedInfo.Sizes.emplace_back(Builder.getInt64(4));
|
||||
CombinedInfo.Types.emplace_back(llvm::omp::OpenMPOffloadMappingFlags(2));
|
||||
uint32_t temp;
|
||||
CombinedInfo.Names.emplace_back(
|
||||
OMPBuilder.getOrCreateSrcLocStr("unknown", temp));
|
||||
return CombinedInfo;
|
||||
};
|
||||
|
||||
llvm::OpenMPIRBuilder::TargetDataInfo Info(
|
||||
/*RequiresDevicePointerInfo=*/false,
|
||||
/*SeparateBeginEndCalls=*/true);
|
||||
|
||||
OMPBuilder.Config.setIsTargetCodegen(true);
|
||||
|
||||
llvm::omp::RuntimeFunction RTLFunc = OMPRTL___tgt_target_data_end_mapper;
|
||||
Builder.restoreIP(OMPBuilder.createTargetData(
|
||||
Loc, Builder.saveIP(), MapTypeFlagsFrom, MapNames, MapperAllocas,
|
||||
/* IsBegin= */ false, DeviceID, /* IfCond= */ nullptr, ProcessMapOpCB));
|
||||
Loc, AllocaIP, Builder.saveIP(), Builder.getInt64(DeviceID),
|
||||
/* IfCond= */ nullptr, Info, GenMapInfoCB, &RTLFunc));
|
||||
|
||||
CallInst *TargetDataCall = dyn_cast<CallInst>(&BB->back());
|
||||
EXPECT_NE(TargetDataCall, nullptr);
|
||||
@ -5038,18 +5000,9 @@ TEST_F(OpenMPIRBuilderTest, TargetDataRegion) {
|
||||
OMPBuilder.initialize();
|
||||
F->setName("func");
|
||||
IRBuilder<> Builder(BB);
|
||||
|
||||
OpenMPIRBuilder::LocationDescription Loc({Builder.saveIP(), DL});
|
||||
|
||||
unsigned NumDataOperands = 1;
|
||||
int64_t DeviceID = 2;
|
||||
struct OpenMPIRBuilder::MapperAllocas MapperAllocas;
|
||||
SmallVector<uint64_t> MapTypeFlagsToFrom = {3};
|
||||
SmallVector<Constant *> MapNames;
|
||||
auto *I8PtrTy = Builder.getInt8PtrTy();
|
||||
auto *ArrI8PtrTy = ArrayType::get(I8PtrTy, NumDataOperands);
|
||||
auto *I64Ty = Builder.getInt64Ty();
|
||||
auto *ArrI64Ty = ArrayType::get(I64Ty, NumDataOperands);
|
||||
|
||||
AllocaInst *Val1 =
|
||||
Builder.CreateAlloca(Builder.getInt32Ty(), Builder.getInt64(1));
|
||||
@ -5057,57 +5010,52 @@ TEST_F(OpenMPIRBuilderTest, TargetDataRegion) {
|
||||
|
||||
IRBuilder<>::InsertPoint AllocaIP(&F->getEntryBlock(),
|
||||
F->getEntryBlock().getFirstInsertionPt());
|
||||
OMPBuilder.createMapperAllocas(Builder.saveIP(), AllocaIP, NumDataOperands,
|
||||
MapperAllocas);
|
||||
|
||||
llvm::OpenMPIRBuilder::MapInfosTy CombinedInfo;
|
||||
using InsertPointTy = OpenMPIRBuilder::InsertPointTy;
|
||||
auto ProcessMapOpCB = [&](InsertPointTy AllocaIP, InsertPointTy CodeGenIP) {
|
||||
Value *DataValue = Val1;
|
||||
Value *DataPtrBase;
|
||||
Value *DataPtr;
|
||||
DataPtrBase = DataValue;
|
||||
DataPtr = DataValue;
|
||||
Builder.restoreIP(CodeGenIP);
|
||||
auto GenMapInfoCB =
|
||||
[&](InsertPointTy codeGenIP) -> llvm::OpenMPIRBuilder::MapInfosTy & {
|
||||
// Get map clause information.
|
||||
Builder.restoreIP(codeGenIP);
|
||||
|
||||
Value *Null = Constant::getNullValue(DataValue->getType()->getPointerTo());
|
||||
Value *SizeGep =
|
||||
Builder.CreateGEP(DataValue->getType(), Null, Builder.getInt32(1));
|
||||
Value *SizePtrToInt = Builder.CreatePtrToInt(SizeGep, I64Ty);
|
||||
|
||||
Value *PtrBaseGEP =
|
||||
Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.ArgsBase,
|
||||
{Builder.getInt32(0), Builder.getInt32(0)});
|
||||
Value *PtrBaseCast = Builder.CreateBitCast(
|
||||
PtrBaseGEP, DataPtrBase->getType()->getPointerTo());
|
||||
Builder.CreateStore(DataPtrBase, PtrBaseCast);
|
||||
Value *PtrGEP =
|
||||
Builder.CreateInBoundsGEP(ArrI8PtrTy, MapperAllocas.Args,
|
||||
{Builder.getInt32(0), Builder.getInt32(0)});
|
||||
Value *PtrCast =
|
||||
Builder.CreateBitCast(PtrGEP, DataPtr->getType()->getPointerTo());
|
||||
Builder.CreateStore(DataPtr, PtrCast);
|
||||
Value *SizeGEP =
|
||||
Builder.CreateInBoundsGEP(ArrI64Ty, MapperAllocas.ArgSizes,
|
||||
{Builder.getInt32(0), Builder.getInt32(0)});
|
||||
Builder.CreateStore(SizePtrToInt, SizeGEP);
|
||||
CombinedInfo.BasePointers.emplace_back(Val1);
|
||||
CombinedInfo.Pointers.emplace_back(Val1);
|
||||
CombinedInfo.Sizes.emplace_back(Builder.getInt64(4));
|
||||
CombinedInfo.Types.emplace_back(llvm::omp::OpenMPOffloadMappingFlags(3));
|
||||
uint32_t temp;
|
||||
CombinedInfo.Names.emplace_back(
|
||||
OMPBuilder.getOrCreateSrcLocStr("unknown", temp));
|
||||
return CombinedInfo;
|
||||
};
|
||||
|
||||
auto BodyCB = [&](InsertPointTy allocaIP, InsertPointTy codeGenIP) {
|
||||
Builder.restoreIP(codeGenIP);
|
||||
auto *SI = Builder.CreateStore(Builder.getInt32(99), Val1);
|
||||
auto *newBB = SplitBlock(Builder.GetInsertBlock(), SI);
|
||||
Builder.SetInsertPoint(newBB);
|
||||
auto *UI = &Builder.GetInsertBlock()->back();
|
||||
SplitBlock(Builder.GetInsertBlock(), UI);
|
||||
llvm::OpenMPIRBuilder::TargetDataInfo Info(
|
||||
/*RequiresDevicePointerInfo=*/false,
|
||||
/*SeparateBeginEndCalls=*/true);
|
||||
|
||||
OMPBuilder.Config.setIsTargetCodegen(true);
|
||||
|
||||
auto BodyCB = [&](InsertPointTy CodeGenIP, int BodyGenType) {
|
||||
if (BodyGenType == 3) {
|
||||
Builder.restoreIP(CodeGenIP);
|
||||
CallInst *TargetDataCall = dyn_cast<CallInst>(&BB->back());
|
||||
EXPECT_NE(TargetDataCall, nullptr);
|
||||
EXPECT_EQ(TargetDataCall->arg_size(), 9U);
|
||||
EXPECT_EQ(TargetDataCall->getCalledFunction()->getName(),
|
||||
"__tgt_target_data_begin_mapper");
|
||||
EXPECT_TRUE(TargetDataCall->getOperand(1)->getType()->isIntegerTy(64));
|
||||
EXPECT_TRUE(TargetDataCall->getOperand(2)->getType()->isIntegerTy(32));
|
||||
EXPECT_TRUE(TargetDataCall->getOperand(8)->getType()->isPointerTy());
|
||||
Builder.restoreIP(CodeGenIP);
|
||||
Builder.CreateStore(Builder.getInt32(99), Val1);
|
||||
}
|
||||
return Builder.saveIP();
|
||||
};
|
||||
|
||||
Builder.restoreIP(OMPBuilder.createTargetData(
|
||||
Loc, Builder.saveIP(), MapTypeFlagsToFrom, MapNames, MapperAllocas,
|
||||
/* IsBegin= */ false, DeviceID, /* IfCond= */ nullptr, ProcessMapOpCB,
|
||||
BodyCB));
|
||||
Loc, AllocaIP, Builder.saveIP(), Builder.getInt64(DeviceID),
|
||||
/* IfCond= */ nullptr, Info, GenMapInfoCB, nullptr, BodyCB));
|
||||
|
||||
CallInst *TargetDataCall =
|
||||
dyn_cast<CallInst>(&Builder.GetInsertBlock()->back());
|
||||
CallInst *TargetDataCall = dyn_cast<CallInst>(&BB->back());
|
||||
EXPECT_NE(TargetDataCall, nullptr);
|
||||
EXPECT_EQ(TargetDataCall->arg_size(), 9U);
|
||||
EXPECT_EQ(TargetDataCall->getCalledFunction()->getName(),
|
||||
|
@ -1361,78 +1361,55 @@ convertOmpThreadprivate(Operation &opInst, llvm::IRBuilderBase &builder,
|
||||
return success();
|
||||
}
|
||||
|
||||
/// Process MapOperands for Target Data directives.
|
||||
static LogicalResult processMapOperand(
|
||||
llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation,
|
||||
const SmallVector<Value> &mapOperands, const ArrayAttr &mapTypes,
|
||||
SmallVector<uint64_t> &mapTypeFlags,
|
||||
SmallVectorImpl<llvm::Constant *> &mapNames,
|
||||
struct llvm::OpenMPIRBuilder::MapperAllocas &mapperAllocas) {
|
||||
auto numMapOperands = mapOperands.size();
|
||||
llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
|
||||
llvm::PointerType *i8PtrTy = builder.getInt8PtrTy();
|
||||
llvm::ArrayType *arrI8PtrTy = llvm::ArrayType::get(i8PtrTy, numMapOperands);
|
||||
llvm::IntegerType *i64Ty = builder.getInt64Ty();
|
||||
llvm::ArrayType *arrI64Ty = llvm::ArrayType::get(i64Ty, numMapOperands);
|
||||
int64_t getSizeInBytes(DataLayout &DL, const mlir::Type &type) {
|
||||
if (isa<LLVM::LLVMPointerType>(type))
|
||||
return DL.getTypeSize(cast<LLVM::LLVMPointerType>(type).getElementType());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void genMapInfos(llvm::IRBuilderBase &builder,
|
||||
LLVM::ModuleTranslation &moduleTranslation,
|
||||
DataLayout &DL,
|
||||
llvm::OpenMPIRBuilder::MapInfosTy &combinedInfo,
|
||||
const SmallVector<Value> &mapOperands,
|
||||
const ArrayAttr &mapTypes) {
|
||||
// Get map clause information.
|
||||
llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
|
||||
unsigned index = 0;
|
||||
for (const auto &mapOp : mapOperands) {
|
||||
const auto &mapTypeOp = mapTypes[index];
|
||||
|
||||
llvm::Value *mapOpValue = moduleTranslation.lookupValue(mapOp);
|
||||
llvm::Value *mapOpPtrBase;
|
||||
llvm::Value *mapOpPtr;
|
||||
llvm::Value *mapOpSize;
|
||||
|
||||
if (isa<LLVM::LLVMPointerType>(mapOp.getType())) {
|
||||
mapOpPtrBase = mapOpValue;
|
||||
mapOpPtr = mapOpValue;
|
||||
mapOpSize = ompBuilder->getSizeInBytes(mapOpValue);
|
||||
} else {
|
||||
return failure();
|
||||
if (!mapOp.getType().isa<LLVM::LLVMPointerType>()) {
|
||||
// TODO: Only LLVMPointerTypes are handled.
|
||||
combinedInfo.BasePointers.clear();
|
||||
combinedInfo.Pointers.clear();
|
||||
combinedInfo.Sizes.clear();
|
||||
combinedInfo.Types.clear();
|
||||
combinedInfo.Names.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// Store base pointer extracted from operand into the i-th position of
|
||||
// argBase.
|
||||
llvm::Value *ptrBaseGEP = builder.CreateInBoundsGEP(
|
||||
arrI8PtrTy, mapperAllocas.ArgsBase,
|
||||
{builder.getInt32(0), builder.getInt32(index)});
|
||||
llvm::Value *ptrBaseCast = builder.CreateBitCast(
|
||||
ptrBaseGEP, mapOpPtrBase->getType()->getPointerTo());
|
||||
builder.CreateStore(mapOpPtrBase, ptrBaseCast);
|
||||
|
||||
// Store pointer extracted from operand into the i-th position of args.
|
||||
llvm::Value *ptrGEP = builder.CreateInBoundsGEP(
|
||||
arrI8PtrTy, mapperAllocas.Args,
|
||||
{builder.getInt32(0), builder.getInt32(index)});
|
||||
llvm::Value *ptrCast =
|
||||
builder.CreateBitCast(ptrGEP, mapOpPtr->getType()->getPointerTo());
|
||||
builder.CreateStore(mapOpPtr, ptrCast);
|
||||
|
||||
// Store size extracted from operand into the i-th position of argSizes.
|
||||
llvm::Value *sizeGEP = builder.CreateInBoundsGEP(
|
||||
arrI64Ty, mapperAllocas.ArgSizes,
|
||||
{builder.getInt32(0), builder.getInt32(index)});
|
||||
builder.CreateStore(mapOpSize, sizeGEP);
|
||||
|
||||
mapTypeFlags.push_back(dyn_cast<mlir::IntegerAttr>(mapTypeOp).getInt());
|
||||
llvm::Constant *mapName =
|
||||
mlir::LLVM::createMappingInformation(mapOp.getLoc(), *ompBuilder);
|
||||
mapNames.push_back(mapName);
|
||||
++index;
|
||||
llvm::Value *mapOpValue = moduleTranslation.lookupValue(mapOp);
|
||||
combinedInfo.BasePointers.emplace_back(mapOpValue);
|
||||
combinedInfo.Pointers.emplace_back(mapOpValue);
|
||||
combinedInfo.Names.emplace_back(
|
||||
mlir::LLVM::createMappingInformation(mapOp.getLoc(), *ompBuilder));
|
||||
combinedInfo.Types.emplace_back(llvm::omp::OpenMPOffloadMappingFlags(
|
||||
mapTypes[index].dyn_cast<mlir::IntegerAttr>().getInt()));
|
||||
combinedInfo.Sizes.emplace_back(
|
||||
builder.getInt64(getSizeInBytes(DL, mapOp.getType())));
|
||||
index++;
|
||||
}
|
||||
|
||||
return success();
|
||||
}
|
||||
|
||||
static LogicalResult
|
||||
convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
|
||||
LLVM::ModuleTranslation &moduleTranslation) {
|
||||
unsigned numMapOperands;
|
||||
llvm::Value *ifCond = nullptr;
|
||||
int64_t deviceID = llvm::omp::OMP_DEVICEID_UNDEF;
|
||||
SmallVector<Value> mapOperands;
|
||||
ArrayAttr mapTypes;
|
||||
llvm::omp::RuntimeFunction RTLFn;
|
||||
DataLayout DL = DataLayout(op->getParentOfType<ModuleOp>());
|
||||
|
||||
llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
|
||||
|
||||
@ -1453,7 +1430,6 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
|
||||
dyn_cast<mlir::IntegerAttr>(constOp.getValue()))
|
||||
deviceID = intAttr.getInt();
|
||||
|
||||
numMapOperands = dataOp.getMapOperands().size();
|
||||
mapOperands = dataOp.getMapOperands();
|
||||
mapTypes = dataOp.getMapTypes();
|
||||
return success();
|
||||
@ -1471,8 +1447,7 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
|
||||
if (auto intAttr =
|
||||
dyn_cast<mlir::IntegerAttr>(constOp.getValue()))
|
||||
deviceID = intAttr.getInt();
|
||||
|
||||
numMapOperands = enterDataOp.getMapOperands().size();
|
||||
RTLFn = llvm::omp::OMPRTL___tgt_target_data_begin_mapper;
|
||||
mapOperands = enterDataOp.getMapOperands();
|
||||
mapTypes = enterDataOp.getMapTypes();
|
||||
return success();
|
||||
@ -1491,7 +1466,7 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
|
||||
dyn_cast<mlir::IntegerAttr>(constOp.getValue()))
|
||||
deviceID = intAttr.getInt();
|
||||
|
||||
numMapOperands = exitDataOp.getMapOperands().size();
|
||||
RTLFn = llvm::omp::OMPRTL___tgt_target_data_end_mapper;
|
||||
mapOperands = exitDataOp.getMapOperands();
|
||||
mapTypes = exitDataOp.getMapTypes();
|
||||
return success();
|
||||
@ -1504,46 +1479,55 @@ convertOmpTargetData(Operation *op, llvm::IRBuilderBase &builder,
|
||||
if (failed(result))
|
||||
return failure();
|
||||
|
||||
using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
|
||||
|
||||
// Fill up the arrays with all the mapped variables.
|
||||
llvm::OpenMPIRBuilder::MapInfosTy combinedInfo;
|
||||
auto genMapInfoCB =
|
||||
[&](InsertPointTy codeGenIP) -> llvm::OpenMPIRBuilder::MapInfosTy & {
|
||||
builder.restoreIP(codeGenIP);
|
||||
genMapInfos(builder, moduleTranslation, DL, combinedInfo, mapOperands,
|
||||
mapTypes);
|
||||
return combinedInfo;
|
||||
};
|
||||
|
||||
LogicalResult bodyGenStatus = success();
|
||||
using BodyGenTy = llvm::OpenMPIRBuilder::BodyGenTy;
|
||||
auto bodyGenCB = [&](InsertPointTy codeGenIP, BodyGenTy bodyGenType) {
|
||||
switch (bodyGenType) {
|
||||
case BodyGenTy::Priv:
|
||||
break;
|
||||
case BodyGenTy::DupNoPriv:
|
||||
break;
|
||||
case BodyGenTy::NoPriv: {
|
||||
// DataOp has only one region associated with it.
|
||||
auto ®ion = cast<omp::DataOp>(op).getRegion();
|
||||
builder.restoreIP(codeGenIP);
|
||||
bodyGenStatus = inlineConvertOmpRegions(region, "omp.data.region",
|
||||
builder, moduleTranslation);
|
||||
}
|
||||
}
|
||||
return builder.saveIP();
|
||||
};
|
||||
|
||||
llvm::OpenMPIRBuilder::LocationDescription ompLoc(builder);
|
||||
llvm::OpenMPIRBuilder::InsertPointTy allocaIP =
|
||||
findAllocaInsertPoint(builder, moduleTranslation);
|
||||
|
||||
struct llvm::OpenMPIRBuilder::MapperAllocas mapperAllocas;
|
||||
SmallVector<uint64_t> mapTypeFlags;
|
||||
SmallVector<llvm::Constant *> mapNames;
|
||||
ompBuilder->createMapperAllocas(builder.saveIP(), allocaIP, numMapOperands,
|
||||
mapperAllocas);
|
||||
|
||||
using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
|
||||
LogicalResult processMapOpStatus = success();
|
||||
auto processMapOpCB = [&](InsertPointTy allocaIP, InsertPointTy codeGenIP) {
|
||||
builder.restoreIP(codeGenIP);
|
||||
processMapOpStatus =
|
||||
processMapOperand(builder, moduleTranslation, mapOperands, mapTypes,
|
||||
mapTypeFlags, mapNames, mapperAllocas);
|
||||
};
|
||||
|
||||
LogicalResult bodyGenStatus = success();
|
||||
auto bodyCB = [&](InsertPointTy allocaIP, InsertPointTy codeGenIP) {
|
||||
// DataOp has only one region associated with it.
|
||||
auto ®ion = cast<omp::DataOp>(op).getRegion();
|
||||
builder.restoreIP(codeGenIP);
|
||||
bodyGenStatus = inlineConvertOmpRegions(region, "omp.data.region", builder,
|
||||
moduleTranslation);
|
||||
};
|
||||
|
||||
// TODO: Add support for DevicePointerInfo
|
||||
llvm::OpenMPIRBuilder::TargetDataInfo info(
|
||||
/*RequiresDevicePointerInfo=*/false,
|
||||
/*SeparateBeginEndCalls=*/true);
|
||||
if (isa<omp::DataOp>(op)) {
|
||||
builder.restoreIP(ompBuilder->createTargetData(
|
||||
ompLoc, builder.saveIP(), mapTypeFlags, mapNames, mapperAllocas,
|
||||
/*IsBegin=*/false, deviceID, ifCond, processMapOpCB, bodyCB));
|
||||
ompLoc, allocaIP, builder.saveIP(), builder.getInt64(deviceID), ifCond,
|
||||
info, genMapInfoCB, nullptr, bodyGenCB));
|
||||
} else {
|
||||
builder.restoreIP(ompBuilder->createTargetData(
|
||||
ompLoc, builder.saveIP(), mapTypeFlags, mapNames, mapperAllocas,
|
||||
isa<omp::EnterDataOp>(op), deviceID, ifCond, processMapOpCB));
|
||||
ompLoc, allocaIP, builder.saveIP(), builder.getInt64(deviceID), ifCond,
|
||||
info, genMapInfoCB, &RTLFn));
|
||||
}
|
||||
|
||||
if (failed(processMapOpStatus))
|
||||
return processMapOpStatus;
|
||||
return bodyGenStatus;
|
||||
}
|
||||
|
||||
@ -1554,7 +1538,7 @@ LogicalResult convertFlagsAttr(Operation *op, mlir::omp::FlagsAttr attribute,
|
||||
LLVM::ModuleTranslation &moduleTranslation) {
|
||||
if (!cast<mlir::ModuleOp>(op))
|
||||
return failure();
|
||||
|
||||
|
||||
llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
|
||||
|
||||
ompBuilder->createGlobalFlag(
|
||||
|
@ -11,29 +11,28 @@ llvm.func @_QPopenmp_target_data() {
|
||||
llvm.return
|
||||
}
|
||||
|
||||
// CHECK: @.offload_sizes = private unnamed_addr constant [1 x i64] [i64 4]
|
||||
// CHECK: @.offload_maptypes = private unnamed_addr constant [1 x i64] [i64 3]
|
||||
// CHECK-LABEL: define void @_QPopenmp_target_data() {
|
||||
// CHECK: %[[VAL_0:.*]] = alloca [1 x ptr], align 8
|
||||
// CHECK: %[[VAL_1:.*]] = alloca [1 x ptr], align 8
|
||||
// CHECK: %[[VAL_2:.*]] = alloca [1 x i64], align 8
|
||||
// CHECK: %[[VAL_2:.*]] = alloca [1 x ptr], align 8
|
||||
// CHECK: %[[VAL_3:.*]] = alloca i32, i64 1, align 4
|
||||
// CHECK: br label %[[VAL_4:.*]]
|
||||
// CHECK: [[VAL_4]]:
|
||||
// CHECK: %[[VAL_5:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
|
||||
// CHECK: store ptr %[[VAL_3]], ptr %[[VAL_5]], align 8
|
||||
// CHECK: %[[VAL_6:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
|
||||
// CHECK: entry: ; preds = %[[VAL_5:.*]]
|
||||
// CHECK: %[[VAL_6:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
|
||||
// CHECK: store ptr %[[VAL_3]], ptr %[[VAL_6]], align 8
|
||||
// CHECK: %[[VAL_7:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0
|
||||
// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_7]], align 4
|
||||
// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
|
||||
// CHECK: %[[VAL_9:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
|
||||
// CHECK: %[[VAL_10:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0
|
||||
// CHECK: call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_8]], ptr %[[VAL_9]], ptr %[[VAL_10]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
|
||||
// CHECK: %[[VAL_7:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
|
||||
// CHECK: store ptr %[[VAL_3]], ptr %[[VAL_7]], align 8
|
||||
// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_2]], i64 0, i64 0
|
||||
// CHECK: store ptr null, ptr %[[VAL_8]], align 8
|
||||
// CHECK: %[[VAL_9:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
|
||||
// CHECK: %[[VAL_10:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
|
||||
// CHECK: call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_9]], ptr %[[VAL_10]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr null, ptr null)
|
||||
// CHECK: store i32 99, ptr %[[VAL_3]], align 4
|
||||
// CHECK: %[[VAL_11:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
|
||||
// CHECK: %[[VAL_12:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
|
||||
// CHECK: %[[VAL_13:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0
|
||||
// CHECK: call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_11]], ptr %[[VAL_12]], ptr %[[VAL_13]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
|
||||
// CHECK: call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_11]], ptr %[[VAL_12]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr null, ptr null)
|
||||
// CHECK: ret void
|
||||
|
||||
// -----
|
||||
@ -51,35 +50,34 @@ llvm.func @_QPopenmp_target_data_region(%1 : !llvm.ptr<array<1024 x i32>>) {
|
||||
llvm.return
|
||||
}
|
||||
|
||||
// CHECK: @.offload_sizes = private unnamed_addr constant [1 x i64] [i64 4096]
|
||||
// CHECK: @.offload_maptypes = private unnamed_addr constant [1 x i64] [i64 2]
|
||||
// CHECK-LABEL: define void @_QPopenmp_target_data_region
|
||||
// CHECK: (ptr %[[ARG_0:.*]]) {
|
||||
// CHECK: %[[VAL_0:.*]] = alloca [1 x ptr], align 8
|
||||
// CHECK: %[[VAL_1:.*]] = alloca [1 x ptr], align 8
|
||||
// CHECK: %[[VAL_2:.*]] = alloca [1 x i64], align 8
|
||||
// CHECK: %[[VAL_2:.*]] = alloca [1 x ptr], align 8
|
||||
// CHECK: br label %[[VAL_3:.*]]
|
||||
// CHECK: [[VAL_3]]:
|
||||
// CHECK: %[[VAL_4:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
|
||||
// CHECK: store ptr %[[VAL_5:.*]], ptr %[[VAL_4]], align 8
|
||||
// CHECK: %[[VAL_6:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
|
||||
// CHECK: store ptr %[[VAL_5]], ptr %[[VAL_6]], align 8
|
||||
// CHECK: %[[VAL_7:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0
|
||||
// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_7]], align 4
|
||||
// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
|
||||
// CHECK: %[[VAL_9:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
|
||||
// CHECK: %[[VAL_10:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0
|
||||
// CHECK: call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_8]], ptr %[[VAL_9]], ptr %[[VAL_10]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
|
||||
// CHECK: %[[VAL_11:.*]] = getelementptr [1024 x i32], ptr %[[VAL_5]], i32 0, i64 0
|
||||
// CHECK: entry: ; preds = %[[VAL_4:.*]]
|
||||
// CHECK: %[[VAL_5:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
|
||||
// CHECK: store ptr %[[VAL_6:.*]], ptr %[[VAL_5]], align 8
|
||||
// CHECK: %[[VAL_7:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
|
||||
// CHECK: store ptr %[[VAL_6]], ptr %[[VAL_7]], align 8
|
||||
// CHECK: %[[VAL_8:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_2]], i64 0, i64 0
|
||||
// CHECK: store ptr null, ptr %[[VAL_8]], align 8
|
||||
// CHECK: %[[VAL_9:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
|
||||
// CHECK: %[[VAL_10:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
|
||||
// CHECK: call void @__tgt_target_data_begin_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_9]], ptr %[[VAL_10]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr null, ptr null)
|
||||
// CHECK: %[[VAL_11:.*]] = getelementptr [1024 x i32], ptr %[[VAL_6]], i32 0, i64 0
|
||||
// CHECK: store i32 99, ptr %[[VAL_11]], align 4
|
||||
// CHECK: %[[VAL_12:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_0]], i32 0, i32 0
|
||||
// CHECK: %[[VAL_13:.*]] = getelementptr inbounds [1 x ptr], ptr %[[VAL_1]], i32 0, i32 0
|
||||
// CHECK: %[[VAL_14:.*]] = getelementptr inbounds [1 x i64], ptr %[[VAL_2]], i32 0, i32 0
|
||||
// CHECK: call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_12]], ptr %[[VAL_13]], ptr %[[VAL_14]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
|
||||
// CHECK: call void @__tgt_target_data_end_mapper(ptr @2, i64 -1, i32 1, ptr %[[VAL_12]], ptr %[[VAL_13]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr null, ptr null)
|
||||
// CHECK: ret void
|
||||
|
||||
// -----
|
||||
|
||||
llvm.func @_QPomp_target_enter_exit(%1 : !llvm.ptr<array<1024 x i32>>, %3 : !llvm.ptr<array<1024 x i32>>) {
|
||||
llvm.func @_QPomp_target_enter_exit(%1 : !llvm.ptr<array<1024 x i32>>, %3 : !llvm.ptr<array<512 x i32>>) {
|
||||
%4 = llvm.mlir.constant(1 : i64) : i64
|
||||
%5 = llvm.alloca %4 x i32 {bindc_name = "dvc", in_type = i32, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFomp_target_enter_exitEdvc"} : (i64) -> !llvm.ptr<i32>
|
||||
%6 = llvm.mlir.constant(1 : i64) : i64
|
||||
@ -92,25 +90,27 @@ llvm.func @_QPomp_target_enter_exit(%1 : !llvm.ptr<array<1024 x i32>>, %3 : !llv
|
||||
%11 = llvm.mlir.constant(10 : i32) : i32
|
||||
%12 = llvm.icmp "slt" %10, %11 : i32
|
||||
%13 = llvm.load %5 : !llvm.ptr<i32>
|
||||
omp.target_enter_data if(%12 : i1) device(%13 : i32) map((to -> %1 : !llvm.ptr<array<1024 x i32>>), (alloc -> %3 : !llvm.ptr<array<1024 x i32>>))
|
||||
omp.target_enter_data if(%12 : i1) device(%13 : i32) map((to -> %1 : !llvm.ptr<array<1024 x i32>>), (alloc -> %3 : !llvm.ptr<array<512 x i32>>))
|
||||
%14 = llvm.load %7 : !llvm.ptr<i32>
|
||||
%15 = llvm.mlir.constant(10 : i32) : i32
|
||||
%16 = llvm.icmp "sgt" %14, %15 : i32
|
||||
%17 = llvm.load %5 : !llvm.ptr<i32>
|
||||
omp.target_exit_data if(%16 : i1) device(%17 : i32) map((from -> %1 : !llvm.ptr<array<1024 x i32>>), (release -> %3 : !llvm.ptr<array<1024 x i32>>))
|
||||
omp.target_exit_data if(%16 : i1) device(%17 : i32) map((from -> %1 : !llvm.ptr<array<1024 x i32>>), (release -> %3 : !llvm.ptr<array<512 x i32>>))
|
||||
llvm.return
|
||||
}
|
||||
|
||||
// CHECK: @.offload_sizes = private unnamed_addr constant [2 x i64] [i64 4096, i64 2048]
|
||||
// CHECK: @.offload_maptypes = private unnamed_addr constant [2 x i64] [i64 1, i64 0]
|
||||
// CHECK: @.offload_maptypes.1 = private unnamed_addr constant [2 x i64] [i64 2, i64 0]
|
||||
// CHECK: @.offload_sizes.1 = private unnamed_addr constant [2 x i64] [i64 4096, i64 2048]
|
||||
// CHECK: @.offload_maptypes.2 = private unnamed_addr constant [2 x i64] [i64 2, i64 0]
|
||||
// CHECK-LABEL: define void @_QPomp_target_enter_exit
|
||||
// CHECK: (ptr %[[ARG_0:.*]], ptr %[[ARG_1:.*]]) {
|
||||
// CHECK: %[[VAL_0:.*]] = alloca [2 x ptr], align 8
|
||||
// CHECK: %[[VAL_1:.*]] = alloca [2 x ptr], align 8
|
||||
// CHECK: %[[VAL_2:.*]] = alloca [2 x i64], align 8
|
||||
// CHECK: %[[VAL_2:.*]] = alloca [2 x ptr], align 8
|
||||
// CHECK: %[[VAL_3:.*]] = alloca [2 x ptr], align 8
|
||||
// CHECK: %[[VAL_4:.*]] = alloca [2 x ptr], align 8
|
||||
// CHECK: %[[VAL_5:.*]] = alloca [2 x i64], align 8
|
||||
// CHECK: %[[VAL_5:.*]] = alloca [2 x ptr], align 8
|
||||
// CHECK: %[[VAL_6:.*]] = alloca i32, i64 1, align 4
|
||||
// CHECK: %[[VAL_7:.*]] = alloca i32, i64 1, align 4
|
||||
// CHECK: store i32 5, ptr %[[VAL_7]], align 4
|
||||
@ -126,44 +126,45 @@ llvm.func @_QPomp_target_enter_exit(%1 : !llvm.ptr<array<1024 x i32>>, %3 : !llv
|
||||
// CHECK: store ptr %[[VAL_16:.*]], ptr %[[VAL_15]], align 8
|
||||
// CHECK: %[[VAL_17:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_4]], i32 0, i32 0
|
||||
// CHECK: store ptr %[[VAL_16]], ptr %[[VAL_17]], align 8
|
||||
// CHECK: %[[VAL_18:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_5]], i32 0, i32 0
|
||||
// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_18]], align 4
|
||||
// CHECK: %[[VAL_18:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_5]], i64 0, i64 0
|
||||
// CHECK: store ptr null, ptr %[[VAL_18]], align 8
|
||||
// CHECK: %[[VAL_19:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_3]], i32 0, i32 1
|
||||
// CHECK: store ptr %[[VAL_20:.*]], ptr %[[VAL_19]], align 8
|
||||
// CHECK: %[[VAL_21:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_4]], i32 0, i32 1
|
||||
// CHECK: store ptr %[[VAL_20]], ptr %[[VAL_21]], align 8
|
||||
// CHECK: %[[VAL_22:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_5]], i32 0, i32 1
|
||||
// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_22]], align 4
|
||||
// CHECK: %[[VAL_22:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_5]], i64 0, i64 1
|
||||
// CHECK: store ptr null, ptr %[[VAL_22]], align 8
|
||||
// CHECK: %[[VAL_23:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_3]], i32 0, i32 0
|
||||
// CHECK: %[[VAL_24:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_4]], i32 0, i32 0
|
||||
// CHECK: %[[VAL_25:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_5]], i32 0, i32 0
|
||||
// CHECK: call void @__tgt_target_data_begin_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_23]], ptr %[[VAL_24]], ptr %[[VAL_25]], ptr @.offload_maptypes, ptr @.offload_mapnames, ptr null)
|
||||
// CHECK: br label %[[VAL_14]]
|
||||
// CHECK: omp_if.end: ; preds = %[[VAL_11]], %[[VAL_13]]
|
||||
// CHECK: call void @__tgt_target_data_begin_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_23]], ptr %[[VAL_24]], ptr @.offload_sizes, ptr @.offload_maptypes, ptr null, ptr null)
|
||||
// CHECK: br label %[[VAL_25:.*]]
|
||||
// CHECK: omp_if.else: ; preds = %[[VAL_11]]
|
||||
// CHECK: br label %[[VAL_25]]
|
||||
// CHECK: omp_if.end: ; preds = %[[VAL_14]], %[[VAL_13]]
|
||||
// CHECK: %[[VAL_26:.*]] = load i32, ptr %[[VAL_7]], align 4
|
||||
// CHECK: %[[VAL_27:.*]] = icmp sgt i32 %[[VAL_26]], 10
|
||||
// CHECK: %[[VAL_28:.*]] = load i32, ptr %[[VAL_6]], align 4
|
||||
// CHECK: br i1 %[[VAL_27]], label %[[VAL_29:.*]], label %[[VAL_30:.*]]
|
||||
// CHECK: omp_if.then4: ; preds = %[[VAL_14]]
|
||||
// CHECK: omp_if.then1: ; preds = %[[VAL_25]]
|
||||
// CHECK: %[[VAL_31:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0
|
||||
// CHECK: store ptr %[[VAL_16]], ptr %[[VAL_31]], align 8
|
||||
// CHECK: %[[VAL_32:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0
|
||||
// CHECK: store ptr %[[VAL_16]], ptr %[[VAL_32]], align 8
|
||||
// CHECK: %[[VAL_33:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_2]], i32 0, i32 0
|
||||
// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_33]], align 4
|
||||
// CHECK: %[[VAL_33:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_2]], i64 0, i64 0
|
||||
// CHECK: store ptr null, ptr %[[VAL_33]], align 8
|
||||
// CHECK: %[[VAL_34:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 1
|
||||
// CHECK: store ptr %[[VAL_20]], ptr %[[VAL_34]], align 8
|
||||
// CHECK: %[[VAL_35:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 1
|
||||
// CHECK: store ptr %[[VAL_20]], ptr %[[VAL_35]], align 8
|
||||
// CHECK: %[[VAL_36:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_2]], i32 0, i32 1
|
||||
// CHECK: store i64 ptrtoint (ptr getelementptr (ptr, ptr null, i32 1) to i64), ptr %[[VAL_36]], align 4
|
||||
// CHECK: %[[VAL_36:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_2]], i64 0, i64 1
|
||||
// CHECK: store ptr null, ptr %[[VAL_36]], align 8
|
||||
// CHECK: %[[VAL_37:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_0]], i32 0, i32 0
|
||||
// CHECK: %[[VAL_38:.*]] = getelementptr inbounds [2 x ptr], ptr %[[VAL_1]], i32 0, i32 0
|
||||
// CHECK: %[[VAL_39:.*]] = getelementptr inbounds [2 x i64], ptr %[[VAL_2]], i32 0, i32 0
|
||||
// CHECK: call void @__tgt_target_data_end_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_37]], ptr %[[VAL_38]], ptr %[[VAL_39]], ptr @.offload_maptypes.1, ptr @.offload_mapnames.2, ptr null)
|
||||
// CHECK: br label %[[VAL_30]]
|
||||
// CHECK: omp_if.end5: ; preds = %[[VAL_14]], %[[VAL_29]]
|
||||
// CHECK: call void @__tgt_target_data_end_mapper(ptr @3, i64 -1, i32 2, ptr %[[VAL_37]], ptr %[[VAL_38]], ptr @.offload_sizes.1, ptr @.offload_maptypes.2, ptr null, ptr null)
|
||||
// CHECK: br label %[[VAL_39:.*]]
|
||||
// CHECK: omp_if.else5: ; preds = %[[VAL_25]]
|
||||
// CHECK: br label %[[VAL_39]]
|
||||
// CHECK: omp_if.end6: ; preds = %[[VAL_30]], %[[VAL_29]]
|
||||
// CHECK: ret void
|
||||
|
||||
// -----
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user