14#include "llvm/ADT/Hashing.h"
15#include "llvm/ADT/STLExtras.h"
16#include "llvm/ADT/SmallString.h"
17#include "llvm/ADT/StringExtras.h"
18#include "llvm/ADT/Twine.h"
26 while (
auto fusedLoc = dyn_cast<FusedLoc>(loc))
27 loc = fusedLoc.getLocations().back();
31std::optional<FileLineColLoc>
35 if (
auto fileLoc = dyn_cast<FileLineColLoc>(unfusedLoc))
38 if (
auto callSiteLoc = dyn_cast<CallSiteLoc>(unfusedLoc)) {
41 if (
auto callerFileLoc =
46 if (errorOnInvalidLocation)
48 "cannot get file:line information: invalid Location information");
55 auto funcOp = dyn_cast<FunctionOpInterface>(op);
58 return funcOp ? funcOp.getName() : StringRef();
68 for (
Value value : values) {
79 return name.str().str();
82 for (
unsigned char c :
detail)
83 name += (llvm::isAlnum(c) || c ==
'_' || c ==
'$' || c ==
'.') ? c :
'_';
84 return name.str().str();
91 StringRef name, StringRef value,
92 Region &globalSymbolRegion,
95 nullTermStr.push_back(
'\0');
106 auto global = dyn_cast<LLVM::GlobalOp>(taken);
107 if (global && global.getValueOrNull() == valueAttr)
110 (name +
"." + Twine(suffix++)).toVector(uniqueName);
118 auto arrayTy = LLVM::LLVMArrayType::get(builder.
getI8Type(),
119 nullTermStr.size_in_bytes());
121 LLVM::GlobalOp::create(builder, loc, arrayTy,
true,
122 LLVM::Linkage::Internal, uniqueName, valueAttr,
125 symbolTable->
insert(global);
130 StringRef name, StringRef value,
131 Region &globalSymbolRegion,
136 loc, builder, name, value, globalSymbolRegion, symbolTable);
138 Value globalPtr = LLVM::AddressOfOp::create(builder, loc, global);
139 Value cst0 = LLVM::ConstantOp::create(builder, loc, i64Ty,
141 return LLVM::GEPOp::create(builder, loc, ptrTy, global.getType(), globalPtr,
146 Region &globalSymbolRegion,
152 Type ptrTy = LLVM::LLVMPointerType::get(ctx);
153 Type structTy = LLVM::LLVMStructType::getLiteral(
154 ctx, {i32Ty, i32Ty, i32Ty, i32Ty, ptrTy});
159 std::string position;
160 if (
auto fileLineColLoc =
162 std::string filename = fileLineColLoc->getFilename().str();
163 std::string line = std::to_string(fileLineColLoc->getLine());
164 std::string column = std::to_string(fileLineColLoc->getColumn());
165 std::string functionDisplayName =
166 functionName.empty() ? std::string()
169 source += filename +
";";
170 source += functionDisplayName +
";";
171 source += line +
";";
172 source += column +
";";
174 position = line +
"." + column +
".";
175 position += std::to_string(
static_cast<uint64_t
>(llvm::hash_value(source)));
177 source =
";unknown;unknown;0;0;;";
178 position =
"unknown";
182 LLVM::GlobalOp identGlobal =
183 symbolTable ? symbolTable->
lookup<LLVM::GlobalOp>(identGlobalName)
188 globalSymbolRegion, symbolTable);
192 identGlobal = LLVM::GlobalOp::create(
193 builder, loc, structTy,
true, LLVM::Linkage::Internal,
196 symbolTable->
insert(identGlobal);
200 Value ident = LLVM::ZeroOp::create(builder, loc, structTy);
201 Value sourceBase = LLVM::AddressOfOp::create(builder, loc, sourceGlobal);
202 Value cst0 = LLVM::ConstantOp::create(builder, loc, i64Ty,
205 LLVM::GEPOp::create(builder, loc, ptrTy, sourceGlobal.getType(),
207 ident = LLVM::InsertValueOp::create(builder, loc, structTy, ident,
209 LLVM::ReturnOp::create(builder, loc, ident);
212 return LLVM::AddressOfOp::create(builder, loc, identGlobal);
219 if (isa<IndexType>(value.
getType()))
220 return arith::IndexCastOp::create(builder, loc, i64Ty, value);
223 return arith::TruncIOp::create(builder, loc, i64Ty, value);
224 return arith::ExtSIOp::create(builder, loc, i64Ty, value);
232 return LLVM::ConstantOp::create(builder, loc, i64Ty,
235 return castToI64(loc, asyncOperand, builder);
236 return LLVM::ConstantOp::create(builder, loc, i64Ty,
242 Region &globalSymbolRegion,
251 queues.reserve(waitOperands.size());
252 for (
Value waitOperand : waitOperands)
253 queues.push_back(
castToI64(loc, waitOperand, builder));
255 unsigned size = queues.size();
256 Value waitNum = LLVM::ConstantOp::create(builder, loc, i32Ty, size);
259 waitList = LLVM::ZeroOp::create(builder, loc, ptrTy);
261 waitList = LLVM::AllocaOp::create(builder, loc, ptrTy, i64Ty, waitNum);
262 for (
auto [
index, queue] : llvm::enumerate(queues)) {
263 Value idx = LLVM::ConstantOp::create(builder, loc, i32Ty,
265 Value elementPtr = LLVM::GEPOp::create(builder, loc, ptrTy, i64Ty,
267 LLVM::StoreOp::create(builder, loc, queue, elementPtr);
272 if (functionName.empty())
276 config, &symbolTable);
277 Value flags = LLVM::ConstantOp::create(builder, loc, i64Ty, 0);
278 Value deviceType = LLVM::ConstantOp::create(
281 deviceNum = LLVM::ConstantOp::create(builder, loc, i32Ty, 0);
284 loc, builder, globalSymbolRegion, symbolTable,
285 RuntimeFunction::ACCRTL_tgt_acc_wait, config,
286 {ident, flags, deviceType, deviceNum, waitNum, waitList, asyncQueue});
291 Region &globalSymbolRegion,
296 globalSymbolRegion, config, &symbolTable);
297 Value flags = LLVM::ConstantOp::create(
305 loc, builder, globalSymbolRegion, symbolTable,
306 RuntimeFunction::ACCRTL_tgt_acc_get_deviceptr, config,
307 {ident, hostPtr, flags, hostPtr});
310 return call->getResult();
316 if (deviceType != DeviceType::None && deviceType != DeviceType::Star)
317 deviceTypes.push_back(deviceType);
318 deviceTypes.push_back(DeviceType::Star);
319 deviceTypes.push_back(DeviceType::None);
330 Block *continueBlock =
336 LLVM::CondBrOp::create(rewriter, loc, ifCond, thenBlock,
ValueRange{},
340 LogicalResult
result = emitFn();
342 LLVM::BrOp::create(rewriter, loc,
ValueRange{}, continueBlock);
356 Block *continueBlock =
364 LLVM::CondBrOp::create(rewriter, loc, ifCond, thenBlock,
ValueRange{},
368 FailureOr<Value> thenValue = thenFn();
369 if (failed(thenValue))
372 LLVM::BrOp::create(rewriter, loc,
ValueRange{*thenValue}, continueBlock);
375 FailureOr<Value> elseValue = elseFn();
376 if (failed(elseValue))
379 LLVM::BrOp::create(rewriter, loc,
ValueRange{*elseValue}, continueBlock);
381 assert(thenValue->getType() == elseValue->getType() &&
382 "both paths of an if clause have to produce the same type");
384 continueBlock->
addArgument(thenValue->getType(), loc);
386 return Value(selected);
394 LLVM::BrOp::create(rewriter, op->
getLoc(), ®ion.
getBlocks().front());
400 LLVM::BrOp::create(rewriter, op->
getLoc(), succ);
403 Operation *terminator = block.getTerminator();
404 if (isa<acc::TerminatorOp>(terminator)) {
406 LLVM::BrOp::create(rewriter, op->
getLoc(), succ);
static LLVM::GlobalOp getOrCreateGlobalStringOp(Location loc, OpBuilder &builder, StringRef name, StringRef value, Region &globalSymbolRegion, SymbolTable *symbolTable)
Creates or reuses a module-internal null-terminated string global and returns the GlobalOp.
Attributes are known-constant values of operations.
This class represents an argument of a Block.
Block represents an ordered list of Operations.
OpListType::iterator iterator
Region * getParent() const
Provide a 'getParent' method for ilist_node_with_parent methods.
BlockArgument addArgument(Type type, Location loc)
Add one value to the argument list.
IntegerAttr getI64IntegerAttr(int64_t value)
StringAttr getStringAttr(const Twine &bytes)
MLIRContext * getContext() const
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MLIRContext is the top-level object for a collection of MLIR operations.
RAII guard to reset the insertion point of the builder when destroyed.
This class helps build Operations.
Block::iterator getInsertionPoint() const
Returns the current insertion point of the builder.
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.
void setInsertionPointToStart(Block *block)
Sets the insertion point to the start of the specified block.
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
void setInsertionPointToEnd(Block *block)
Sets the insertion point to the end of the specified block.
Block * getInsertionBlock() const
Return the block the current insertion point belongs to.
void setInsertionPointAfter(Operation *op)
Sets the insertion point to the node after the specified operation, which will cause subsequent inser...
This class provides the API for ops that are known to be terminators.
Operation is the basic unit of execution within MLIR.
Block * getBlock()
Returns the operation block that contains this operation.
Location getLoc()
The source location the operation was defined or derived from.
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
BlockListType & getBlocks()
BlockListType::iterator iterator
This class coordinates the application of a rewrite on a set of IR, providing a way for clients to tr...
Block * splitBlock(Block *block, Block::iterator before)
Split the operations starting at "before" (inclusive) out of the given block into a new block,...
virtual void eraseOp(Operation *op)
This method erases an operation that is known to have no uses.
void inlineRegionBefore(Region ®ion, Region &parent, Region::iterator before)
Move the blocks that belong to "region" before the given position in another region "parent".
This class allows for representing and managing the symbol table used by operations with the 'SymbolT...
Operation * lookup(StringRef name) const
Look up a symbol with the specified name, returning null if no such name exists.
StringAttr insert(Operation *symbol, Block::iterator insertPt={})
Insert a new symbol into the table, and rename it as necessary to avoid collisions.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
unsigned getIntOrFloatBitWidth() const
Return the bit width of an integer or a float type, assert failure on other types.
This class provides an abstraction over the different types of ranges over Values.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Type getType() const
Return the type of this value.
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
Configuration for OpenACC to LLVM runtime lowering.
int64_t getAsyncNoValueRuntimeValue() const
std::string getFunctionDisplayName(StringRef mangledOrSymbol) const
int64_t getAsyncSyncRuntimeValue() const
int64_t getDeviceTypeRuntimeValue(DeviceType type) const
int64_t getMapFlagsRuntimeValue(MapFlags flags) const
SmallVector< DeviceType, 3 > getDeviceTypesByPrecedence(DeviceType deviceType)
The clauses of a construct can be given once per device type.
std::optional< FileLineColLoc > getFileLineColLoc(Location loc, bool errorOnInvalidLocation)
Returns file:line:column location information when available.
LogicalResult emitWaitCall(Location loc, ValueRange waitOperands, Value asyncQueue, OpBuilder &builder, Region &globalSymbolRegion, SymbolTable &symbolTable, const ACCRuntimeCallConfig &config, Value deviceNum={})
Emits the runtime call that waits for waitOperands on asyncQueue, which is what a wait clause or an a...
Value getAsyncQueue(Location loc, Value asyncOperand, bool asyncOnly, OpBuilder &builder, const ACCRuntimeCallConfig &config)
Returns the queue an async clause selects: the value of the clause when it has one,...
Value createIdent(Location loc, StringRef functionName, OpBuilder &builder, Region &globalSymbolRegion, const ACCRuntimeCallConfig &config, SymbolTable *symbolTable=nullptr)
Returns a pointer to a constant global holding an ident_t for OpenACC runtime calls.
FailureOr< Value > emitValueSelectedByIfCond(Location loc, Value ifCond, RewriterBase &rewriter, function_ref< FailureOr< Value >()> thenFn, function_ref< FailureOr< Value >()> elseFn)
Emits thenFn on the path a branch on ifCond takes and elseFn on the other one, and returns the value ...
std::string getInternalGlobalName(StringRef kind, StringRef detail)
Returns the name to give a global that the conversion creates to hold detail of kind,...
StringRef getParentFunctionName(Operation *op)
Returns the symbol name of the function op belongs to, or of op itself when it is a function.
LogicalResult emitGuardedByIfCond(Location loc, Value ifCond, RewriterBase &rewriter, function_ref< LogicalResult()> emitFn)
Runs emitFn guarded by a branch on ifCond, or unguarded when there is no condition.
Value castToI64(Location loc, Value value, OpBuilder &builder)
Sign-extends or truncates value to the i64 the runtime entry points take for values like queue number...
Value getOrCreateGlobalString(Location loc, OpBuilder &builder, StringRef name, StringRef value, Region &globalSymbolRegion, SymbolTable *symbolTable=nullptr)
Creates or reuses a null-terminated string global in globalSymbolRegion.
void spliceConstructRegion(Operation *op, Region ®ion, RewriterBase &rewriter)
Splices region, the body of a structured construct, into the block holding op, so that the construct ...
FailureOr< LLVM::CallOp > createRuntimeCall(Location loc, OpBuilder &builder, Region &globalSymbolRegion, SymbolTable &symbolTable, RuntimeFunction fn, const ACCRuntimeCallConfig &config, ArrayRef< Value > arguments)
Declares (if needed) and returns a call to the runtime function identified by fn using the name from ...
Location unfuseLoc(Location loc)
Unfuses fused locations, returning the last sub-location.
FailureOr< Value > emitGetDevicePtrCall(Operation *clauseOp, Value hostPtr, bool ifPresent, OpBuilder &builder, Region &globalSymbolRegion, SymbolTable &symbolTable, const ACCRuntimeCallConfig &config)
Emits the runtime call that asks for the device address the object of the data clause clauseOp is map...
Include the generated interface declarations.
llvm::function_ref< Fn > function_ref