64 changes: 33 additions & 31 deletions llvm/lib/Frontend/OpenMP/OMPIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4692,77 +4692,79 @@ void OpenMPIRBuilder::OutlineInfo::collectBlocks(
}
}

void TargetRegionEntryInfo::getTargetRegionEntryFnName(
SmallVectorImpl<char> &Name, StringRef ParentName, unsigned DeviceID,
unsigned FileID, unsigned Line) {
raw_svector_ostream OS(Name);
OS << "__omp_offloading" << llvm::format("_%x", DeviceID)
<< llvm::format("_%x_", FileID) << ParentName << "_l" << Line;
}

void TargetRegionEntryInfo::getTargetRegionEntryFnName(
SmallVectorImpl<char> &Name) {
getTargetRegionEntryFnName(Name, ParentName, DeviceID, FileID, Line);
}

bool OffloadEntriesInfoManager::empty() const {
return OffloadEntriesTargetRegion.empty() &&
OffloadEntriesDeviceGlobalVar.empty();
}

/// Initialize target region entry.
void OffloadEntriesInfoManager::initializeTargetRegionEntryInfo(
const TargetRegionEntryInfo &EntryInfo, unsigned Order) {
OffloadEntriesTargetRegion[EntryInfo] =
unsigned DeviceID, unsigned FileID, StringRef ParentName, unsigned LineNum,
unsigned Order) {
OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] =
OffloadEntryInfoTargetRegion(Order, /*Addr=*/nullptr, /*ID=*/nullptr,
OMPTargetRegionEntryTargetRegion);
++OffloadingEntriesNum;
}

void OffloadEntriesInfoManager::registerTargetRegionEntryInfo(
const TargetRegionEntryInfo &EntryInfo, Constant *Addr, Constant *ID,
OMPTargetRegionEntryKind Flags, bool IsDevice) {
unsigned DeviceID, unsigned FileID, StringRef ParentName, unsigned LineNum,
Constant *Addr, Constant *ID, OMPTargetRegionEntryKind Flags,
bool IsDevice) {
// If we are emitting code for a target, the entry is already initialized,
// only has to be registered.
if (IsDevice) {
// This could happen if the device compilation is invoked standalone.
if (!hasTargetRegionEntryInfo(EntryInfo)) {
if (!hasTargetRegionEntryInfo(DeviceID, FileID, ParentName, LineNum))
return;
}
auto &Entry = OffloadEntriesTargetRegion[EntryInfo];
auto &Entry =
OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum];
Entry.setAddress(Addr);
Entry.setID(ID);
Entry.setFlags(Flags);
} else {
if (Flags == OffloadEntriesInfoManager::OMPTargetRegionEntryTargetRegion &&
hasTargetRegionEntryInfo(EntryInfo, /*IgnoreAddressId*/ true))
hasTargetRegionEntryInfo(DeviceID, FileID, ParentName, LineNum,
/*IgnoreAddressId*/ true))
return;
assert(!hasTargetRegionEntryInfo(EntryInfo) &&
assert(!hasTargetRegionEntryInfo(DeviceID, FileID, ParentName, LineNum) &&
"Target region entry already registered!");
OffloadEntryInfoTargetRegion Entry(OffloadingEntriesNum, Addr, ID, Flags);
OffloadEntriesTargetRegion[EntryInfo] = Entry;
OffloadEntriesTargetRegion[DeviceID][FileID][ParentName][LineNum] = Entry;
++OffloadingEntriesNum;
}
}

bool OffloadEntriesInfoManager::hasTargetRegionEntryInfo(
const TargetRegionEntryInfo &EntryInfo, bool IgnoreAddressId) const {
auto It = OffloadEntriesTargetRegion.find(EntryInfo);
if (It == OffloadEntriesTargetRegion.end()) {
unsigned DeviceID, unsigned FileID, StringRef ParentName, unsigned LineNum,
bool IgnoreAddressId) const {
auto PerDevice = OffloadEntriesTargetRegion.find(DeviceID);
if (PerDevice == OffloadEntriesTargetRegion.end())
return false;
auto PerFile = PerDevice->second.find(FileID);
if (PerFile == PerDevice->second.end())
return false;
auto PerParentName = PerFile->second.find(ParentName);
if (PerParentName == PerFile->second.end())
return false;
auto PerLine = PerParentName->second.find(LineNum);
if (PerLine == PerParentName->second.end())
return false;
}
// Fail if this entry is already registered.
if (!IgnoreAddressId && (It->second.getAddress() || It->second.getID()))
if (!IgnoreAddressId &&
(PerLine->second.getAddress() || PerLine->second.getID()))
return false;
return true;
}

void OffloadEntriesInfoManager::actOnTargetRegionEntriesInfo(
const OffloadTargetRegionEntryInfoActTy &Action) {
// Scan all target region entries and perform the provided action.
for (const auto &It : OffloadEntriesTargetRegion) {
Action(It.first, It.second);
}
for (const auto &D : OffloadEntriesTargetRegion)
for (const auto &F : D.second)
for (const auto &P : F.second)
for (const auto &L : P.second)
Action(D.first, F.first, P.first(), L.first, L.second);
}

void OffloadEntriesInfoManager::initializeDeviceGlobalVarEntryInfo(
Expand Down
7 changes: 3 additions & 4 deletions llvm/unittests/Frontend/OpenMPIRBuilderTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5504,17 +5504,16 @@ TEST_F(OpenMPIRBuilderTest, EmitOffloadingArraysArguments) {

TEST_F(OpenMPIRBuilderTest, OffloadEntriesInfoManager) {
OffloadEntriesInfoManager InfoManager;
TargetRegionEntryInfo EntryInfo("parent", 1, 2, 4);
InfoManager.initializeTargetRegionEntryInfo(EntryInfo, 0);
InfoManager.initializeTargetRegionEntryInfo(1, 2, "parent", 4, 0);
InfoManager.initializeDeviceGlobalVarEntryInfo(
"gvar", OffloadEntriesInfoManager::OMPTargetGlobalVarEntryTo, 0);
InfoManager.registerTargetRegionEntryInfo(
EntryInfo, nullptr, nullptr,
1, 2, "parent", 4, nullptr, nullptr,
OffloadEntriesInfoManager::OMPTargetRegionEntryTargetRegion, true);
InfoManager.registerDeviceGlobalVarEntryInfo(
"gvar", 0x0, 8, OffloadEntriesInfoManager::OMPTargetGlobalVarEntryTo,
GlobalValue::WeakAnyLinkage, true);
EXPECT_TRUE(InfoManager.hasTargetRegionEntryInfo(EntryInfo, true));
EXPECT_TRUE(InfoManager.hasTargetRegionEntryInfo(1, 2, "parent", 4, true));
EXPECT_TRUE(InfoManager.hasDeviceGlobalVarEntryInfo("gvar"));
}
} // namespace