MLIR 24.0.0git
ACCToLLVMUtils.cpp
Go to the documentation of this file.
1//===- ACCToLLVMUtils.cpp - OpenACC to LLVM helpers -------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
13#include "llvm/ADT/Hashing.h"
14#include "llvm/ADT/SmallString.h"
15
16using namespace mlir;
17using namespace mlir::acc;
18
20 while (auto fusedLoc = dyn_cast<FusedLoc>(loc))
21 loc = fusedLoc.getLocations().back();
22 return loc;
23}
24
25std::optional<FileLineColLoc>
26acc::getFileLineColLoc(Location loc, bool errorOnInvalidLocation) {
27 Location unfusedLoc = unfuseLoc(loc);
28
29 if (auto fileLoc = dyn_cast<FileLineColLoc>(unfusedLoc))
30 return fileLoc;
31
32 if (auto callSiteLoc = dyn_cast<CallSiteLoc>(unfusedLoc)) {
33 if (auto calleeFileLoc = getFileLineColLoc(callSiteLoc.getCallee(), false))
34 return calleeFileLoc;
35 if (auto callerFileLoc =
36 getFileLineColLoc(callSiteLoc.getCaller(), errorOnInvalidLocation))
37 return callerFileLoc;
38 }
39
40 if (errorOnInvalidLocation)
41 llvm_unreachable(
42 "cannot get file:line information: invalid Location information");
43 return std::nullopt;
44}
45
47 if (!op)
48 return "";
49 if (auto parentFuncOp = op->getParentOfType<func::FuncOp>())
50 return parentFuncOp.getName();
51 if (auto parentFuncOp = op->getParentOfType<LLVM::LLVMFuncOp>())
52 return parentFuncOp.getSymName();
53 return "";
54}
55
57 if (auto *op = value.getDefiningOp())
58 return getParentFunctionName(op);
59 return "";
60}
61
63 for (Value value : values) {
64 if (StringRef name = getParentFunctionName(value); !name.empty())
65 return name;
66 }
67 return "";
68}
69
70/// Creates or reuses a module-internal null-terminated string global and
71/// returns the GlobalOp.
72static LLVM::GlobalOp getOrCreateGlobalStringOp(Location loc,
73 OpBuilder &builder,
74 StringRef name, StringRef value,
75 ModuleOp module) {
76 if (auto global = module.lookupSymbol<LLVM::GlobalOp>(name))
77 return global;
78
79 // Materialize the global through the incoming builder so that it stays
80 // tracked when the caller is a dialect conversion rewriter.
81 OpBuilder::InsertionGuard guard(builder);
82 builder.setInsertionPointToStart(module.getBody());
83 SmallString<32> nullTermStr(value);
84 nullTermStr.push_back('\0');
85 auto arrayTy = LLVM::LLVMArrayType::get(builder.getI8Type(),
86 nullTermStr.size_in_bytes());
87 return LLVM::GlobalOp::create(builder, loc, arrayTy, /*isConstant=*/true,
88 LLVM::Linkage::Internal, name,
89 builder.getStringAttr(nullTermStr),
90 /*alignment=*/0);
91}
92
94 StringRef name, StringRef value,
95 ModuleOp module) {
96 Type i64Ty = builder.getI64Type();
97 Type ptrTy = LLVM::LLVMPointerType::get(builder.getContext());
98 LLVM::GlobalOp global =
99 getOrCreateGlobalStringOp(loc, builder, name, value, module);
100
101 Value globalPtr = LLVM::AddressOfOp::create(builder, loc, global);
102 Value cst0 =
103 LLVM::ConstantOp::create(builder, loc, i64Ty, builder.getIndexAttr(0));
104 return LLVM::GEPOp::create(builder, loc, ptrTy, global.getType(), globalPtr,
105 ArrayRef<Value>({cst0, cst0}));
106}
107
108Value acc::createIdent(Location loc, StringRef functionName, OpBuilder &builder,
109 ModuleOp module, const ACCRuntimeCallConfig &config) {
110 MLIRContext *ctx = builder.getContext();
111 Type i32Ty = builder.getI32Type();
112 Type i64Ty = builder.getI64Type();
113 Type ptrTy = LLVM::LLVMPointerType::get(ctx);
114 Type structTy = LLVM::LLVMStructType::getLiteral(
115 ctx, {i32Ty, i32Ty, i32Ty, i32Ty, ptrTy});
116
117 std::string source;
118 std::string sourceGlobalName;
119 if (auto fileLineColLoc =
120 getFileLineColLoc(loc, /*errorOnInvalidLocation=*/false)) {
121 std::string filename = fileLineColLoc->getFilename().str();
122 std::string line = std::to_string(fileLineColLoc->getLine());
123 std::string column = std::to_string(fileLineColLoc->getColumn());
124 std::string functionDisplayName =
125 functionName.empty() ? std::string()
126 : config.getFunctionDisplayName(functionName);
127 source = ";";
128 source += filename + ";";
129 source += functionDisplayName + ";";
130 source += line + ";";
131 source += column + ";";
132 source += ";";
133 sourceGlobalName = "loc_";
134 sourceGlobalName += line + "_";
135 sourceGlobalName += column + "_";
136 sourceGlobalName +=
137 std::to_string(static_cast<uint64_t>(llvm::hash_value(source)));
138 } else {
139 source = ";unknown;unknown;0;0;;";
140 sourceGlobalName = "loc__";
141 }
142
143 std::string identGlobalName = "ident_";
144 identGlobalName += sourceGlobalName;
145 auto identGlobal = module.lookupSymbol<LLVM::GlobalOp>(identGlobalName);
146 if (!identGlobal) {
147 LLVM::GlobalOp sourceGlobal = getOrCreateGlobalStringOp(
148 loc, builder, sourceGlobalName, source, module);
149
150 OpBuilder::InsertionGuard guard(builder);
151 builder.setInsertionPointAfter(sourceGlobal);
152 identGlobal = LLVM::GlobalOp::create(
153 builder, loc, structTy, /*isConstant=*/true, LLVM::Linkage::Internal,
154 identGlobalName, /*value=*/Attribute(), /*alignment=*/0);
155
156 Block *block = builder.createBlock(&identGlobal.getInitializerRegion());
157 builder.setInsertionPointToStart(block);
158 Value ident = LLVM::ZeroOp::create(builder, loc, structTy);
159 Value sourceBase = LLVM::AddressOfOp::create(builder, loc, sourceGlobal);
160 Value cst0 =
161 LLVM::ConstantOp::create(builder, loc, i64Ty, builder.getIndexAttr(0));
162 Value sourcePtr =
163 LLVM::GEPOp::create(builder, loc, ptrTy, sourceGlobal.getType(),
164 sourceBase, ArrayRef<Value>({cst0, cst0}));
165 ident = LLVM::InsertValueOp::create(builder, loc, structTy, ident,
166 sourcePtr, ArrayRef<int64_t>{4});
167 LLVM::ReturnOp::create(builder, loc, ident);
168 }
169
170 return LLVM::AddressOfOp::create(builder, loc, identGlobal);
171}
static LLVM::GlobalOp getOrCreateGlobalStringOp(Location loc, OpBuilder &builder, StringRef name, StringRef value, ModuleOp module)
Creates or reuses a module-internal null-terminated string global and returns the GlobalOp.
Attributes are known-constant values of operations.
Definition Attributes.h:25
Block represents an ordered list of Operations.
Definition Block.h:33
IntegerAttr getIndexAttr(int64_t value)
Definition Builders.cpp:116
IntegerType getI64Type()
Definition Builders.cpp:73
IntegerType getI32Type()
Definition Builders.cpp:71
StringAttr getStringAttr(const Twine &bytes)
Definition Builders.cpp:271
MLIRContext * getContext() const
Definition Builders.h:56
IntegerType getI8Type()
Definition Builders.cpp:67
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
RAII guard to reset the insertion point of the builder when destroyed.
Definition Builders.h:351
This class helps build Operations.
Definition Builders.h:210
Block * createBlock(Region *parent, Region::iterator insertPt={}, TypeRange argTypes={}, ArrayRef< Location > locs={})
Add new block with 'argTypes' arguments and set the insertion point to the end of it.
Definition Builders.cpp:439
void setInsertionPointToStart(Block *block)
Sets the insertion point to the start of the specified block.
Definition Builders.h:434
void setInsertionPointAfter(Operation *op)
Sets the insertion point to the node after the specified operation, which will cause subsequent inser...
Definition Builders.h:415
Operation is the basic unit of execution within MLIR.
Definition Operation.h:87
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
Definition Operation.h:255
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
This class provides an abstraction over the different types of ranges over Values.
Definition ValueRange.h:389
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
Definition Value.cpp:18
Optional overrides for OpenACC to LLVM runtime lowering.
std::string getFunctionDisplayName(StringRef mangledOrSymbol) const
std::optional< FileLineColLoc > getFileLineColLoc(Location loc, bool errorOnInvalidLocation)
Returns file:line:column location information when available.
Value getOrCreateGlobalString(Location loc, OpBuilder &builder, StringRef name, StringRef value, ModuleOp module)
Creates or reuses a module-internal null-terminated string global.
Value createIdent(Location loc, StringRef functionName, OpBuilder &builder, ModuleOp module, const ACCRuntimeCallConfig &config)
Returns a pointer to a constant global holding an ident_t for OpenACC runtime calls.
StringRef getParentFunctionName(Operation *op)
Returns the enclosing function symbol name for op.
Location unfuseLoc(Location loc)
Unfuses fused locations, returning the last sub-location.
Include the generated interface declarations.