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);
228 return LLVM::ConstantOp::create(builder, loc, builder.
getI64Type(), value);
234 if (
Value converted = rewriter.getRemappedValue(value))
244 return LLVM::ConstantOp::create(builder, loc, i64Ty,
247 return castToI64(loc, asyncOperand, builder);
248 return LLVM::ConstantOp::create(builder, loc, i64Ty,
254 Region &globalSymbolRegion,
263 queues.reserve(waitOperands.size());
264 for (
Value waitOperand : waitOperands)
265 queues.push_back(
castToI64(loc, waitOperand, builder));
267 unsigned size = queues.size();
268 Value waitNum = LLVM::ConstantOp::create(builder, loc, i32Ty, size);
271 waitList = LLVM::ZeroOp::create(builder, loc, ptrTy);
273 waitList = LLVM::AllocaOp::create(builder, loc, ptrTy, i64Ty, waitNum);
274 for (
auto [
index, queue] : llvm::enumerate(queues)) {
275 Value idx = LLVM::ConstantOp::create(builder, loc, i32Ty,
277 Value elementPtr = LLVM::GEPOp::create(builder, loc, ptrTy, i64Ty,
279 LLVM::StoreOp::create(builder, loc, queue, elementPtr);
284 if (functionName.empty())
288 config, &symbolTable);
289 Value flags = LLVM::ConstantOp::create(builder, loc, i64Ty, 0);
290 Value deviceType = LLVM::ConstantOp::create(
293 deviceNum = LLVM::ConstantOp::create(builder, loc, i32Ty, 0);
296 loc, builder, globalSymbolRegion, symbolTable,
297 RuntimeFunction::ACCRTL_tgt_acc_wait, config,
298 {ident, flags, deviceType, deviceNum, waitNum, waitList, asyncQueue});
303 Region &globalSymbolRegion,
308 globalSymbolRegion, config, &symbolTable);
309 Value flags = LLVM::ConstantOp::create(
317 loc, builder, globalSymbolRegion, symbolTable,
318 RuntimeFunction::ACCRTL_tgt_acc_get_deviceptr, config,
319 {ident, hostPtr, flags, hostPtr});
322 return call->getResult();
332 Block *continueBlock =
338 LLVM::CondBrOp::create(rewriter, loc, ifCond, thenBlock,
ValueRange{},
342 LogicalResult
result = emitFn();
344 LLVM::BrOp::create(rewriter, loc,
ValueRange{}, continueBlock);
358 Block *continueBlock =
366 LLVM::CondBrOp::create(rewriter, loc, ifCond, thenBlock,
ValueRange{},
370 FailureOr<Value> thenValue = thenFn();
371 if (failed(thenValue))
374 LLVM::BrOp::create(rewriter, loc,
ValueRange{*thenValue}, continueBlock);
377 FailureOr<Value> elseValue = elseFn();
378 if (failed(elseValue))
381 LLVM::BrOp::create(rewriter, loc,
ValueRange{*elseValue}, continueBlock);
383 assert(thenValue->getType() == elseValue->getType() &&
384 "both paths of an if clause have to produce the same type");
386 continueBlock->
addArgument(thenValue->getType(), loc);
388 return Value(selected);
396 LLVM::BrOp::create(rewriter, op->
getLoc(), ®ion.
getBlocks().front());
402 LLVM::BrOp::create(rewriter, op->
getLoc(), succ);
405 Operation *terminator = block.getTerminator();
406 if (isa<acc::TerminatorOp>(terminator)) {
408 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
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.
Value remapOrSelf(Value value, ConversionPatternRewriter &rewriter)
Returns the value value was converted to, or value itself when the conversion left it as it was.
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 ...
Value constantI64(Location loc, int64_t value, OpBuilder &builder)
Creates an i64 constant.
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