llvm_util.h revision ea125c27974135fbad6bcb75b720499c68d52357
11e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins/* Copyright 2017 The TensorFlow Authors. All Rights Reserved. 21e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 31e67c90e2caceeff82d09793d1ef5fa0300d219bPeter HawkinsLicensed under the Apache License, Version 2.0 (the "License"); 41e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsyou may not use this file except in compliance with the License. 51e67c90e2caceeff82d09793d1ef5fa0300d219bPeter HawkinsYou may obtain a copy of the License at 61e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 71e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins http://www.apache.org/licenses/LICENSE-2.0 81e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 91e67c90e2caceeff82d09793d1ef5fa0300d219bPeter HawkinsUnless required by applicable law or agreed to in writing, software 101e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsdistributed under the License is distributed on an "AS IS" BASIS, 111e67c90e2caceeff82d09793d1ef5fa0300d219bPeter HawkinsWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 121e67c90e2caceeff82d09793d1ef5fa0300d219bPeter HawkinsSee the License for the specific language governing permissions and 131e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinslimitations under the License. 141e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins==============================================================================*/ 151e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 161e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#ifndef TENSORFLOW_COMPILER_XLA_SERVICE_LLVM_IR_LLVM_UTIL_H_ 171e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#define TENSORFLOW_COMPILER_XLA_SERVICE_LLVM_IR_LLVM_UTIL_H_ 181e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 191e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#include <stdint.h> 201e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#include <string> 211e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#include <vector> 221e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 231e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#include "external/llvm/include/llvm/ADT/StringRef.h" 241e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#include "external/llvm/include/llvm/IR/BasicBlock.h" 251e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#include "external/llvm/include/llvm/IR/IRBuilder.h" 261e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#include "external/llvm/include/llvm/IR/Instructions.h" 271e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#include "external/llvm/include/llvm/IR/Module.h" 281e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#include "external/llvm/include/llvm/IR/Value.h" 291e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#include "external/llvm/include/llvm/Support/raw_ostream.h" 3002ac85399d4fb35d5055ecf426632b9446a70041A. Unique TensorFlower#include "tensorflow/compiler/xla/literal_util.h" 311e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#include "tensorflow/compiler/xla/types.h" 321e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#include "tensorflow/compiler/xla/xla_data.pb.h" 331e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#include "tensorflow/core/lib/core/stringpiece.h" 341e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#include "tensorflow/core/lib/gtl/array_slice.h" 351e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#include "tensorflow/core/platform/types.h" 361e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 371e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsnamespace llvm { 381e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsclass FastMathFlags; 391e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsclass TargetOptions; 401e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins}; 411e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 421e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsnamespace xla { 431e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsnamespace llvm_ir { 441e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 451e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Convert a std::string (used by LLVM's interfaces) to string. 461e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsstring AsString(const std::string& str); 471e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 481e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Convert a tensorflow::StringPiece to a llvm::StringRef. Note: both 491e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// tensorflow::StringPiece and llvm::StringRef are non-owning pointers into a 501e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// string in memory. This method is used to feed strings to LLVM 511e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// & Clang APIs that expect llvm::StringRef. 521e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsllvm::StringRef AsStringRef(tensorflow::StringPiece str); 531e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 541e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinstemplate <typename T> 551e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsllvm::ArrayRef<T> AsArrayRef(const std::vector<T>& vec) { 561e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins return llvm::ArrayRef<T>(vec.data(), vec.size()); 571e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins} 581e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 591e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinstemplate <typename T> 601e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsllvm::ArrayRef<T> AsArrayRef(const tensorflow::gtl::ArraySlice<T>& slice) { 611e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins return llvm::ArrayRef<T>(slice.data(), slice.size()); 621e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins} 631e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 641e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Dump the given LLVM entity to a string. This works for Types and Values. 651e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinstemplate <typename T> 661e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsstring DumpToString(const T& entity) { 671e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins std::string buffer_string; 681e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::raw_string_ostream ostream(buffer_string); 691e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins entity.print(ostream); 701e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins ostream.flush(); 711e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins return AsString(buffer_string); 721e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins} 731e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 741e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Dump the given LLVM module to a string. This requires a function distinct 751e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// from DumpToString because the signatures of the print() methods for Values 761e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// and Modules are slightly different. 771e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsstring DumpModuleToString(const llvm::Module& module); 781e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 791e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Sanitizes the given name to be a valid LLVM IR value name. 801e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsstring SanitizeIrName(string name); 811e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 821e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Emits a call to the specified intrinsic with the given operands. Overloaded 831e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// intrinsics (for example, "minnum") must include a type in overloaded_types 841e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// for each overloaded type. Typically, overloaded intrinsics have only a single 851e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// overloaded type. 861e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsllvm::Value* EmitCallToIntrinsic( 871e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::Intrinsic::ID intrinsic_id, 881e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins tensorflow::gtl::ArraySlice<llvm::Value*> operands, 891e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins tensorflow::gtl::ArraySlice<llvm::Type*> overloaded_types, 901e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::IRBuilder<>* ir_builder); 911e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 921e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Convenience methods for emitting a GEP instruction that indexes into a buffer 931e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// (1-dimensional array), equivalent to array[index]. The type is automatically 941e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// determined from the element type of the array. The int64 index overload 951e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// wraps the index in a i64 llvm::Value. 961e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsllvm::Value* EmitBufferIndexingGEP(llvm::Value* array, llvm::Value* index, 971e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::IRBuilder<>* ir_builder); 981e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsllvm::Value* EmitBufferIndexingGEP(llvm::Value* array, int64 index, 991e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::IRBuilder<>* ir_builder); 1001e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 1011e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Returns the LLVM type which represents the given XLA primitive type. 1021e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsllvm::Type* PrimitiveTypeToIrType(PrimitiveType element_type, 1031e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::IRBuilder<>* ir_builder); 1041e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 1051e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Returns the LLVM type which represents the given XLA shape. For example, 1061e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// if "shape" is [5 x [10 x f32]], the function returns [5 x [10 x float]]. 1071e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsllvm::Type* ShapeToIrType(const Shape& shape, llvm::IRBuilder<>* ir_builder); 1081e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 109ea125c27974135fbad6bcb75b720499c68d52357A. Unique TensorFlower// Returns a value that represents a pointer to a global string constant that 110ea125c27974135fbad6bcb75b720499c68d52357A. Unique TensorFlower// encodes the shape as a serialized protobuf. 111ea125c27974135fbad6bcb75b720499c68d52357A. Unique TensorFlowerStatusOr<llvm::Value*> EncodeSelfDescribingShapeConstant( 112ea125c27974135fbad6bcb75b720499c68d52357A. Unique TensorFlower const Shape& shape, int32* shape_size, llvm::IRBuilder<>* ir_builder); 113ea125c27974135fbad6bcb75b720499c68d52357A. Unique TensorFlower 114ea125c27974135fbad6bcb75b720499c68d52357A. Unique TensorFlower// Inverses the encoding of a Shape protobuf into an LLVM global variable. 115ea125c27974135fbad6bcb75b720499c68d52357A. Unique TensorFlower// 116ea125c27974135fbad6bcb75b720499c68d52357A. Unique TensorFlower// This is intended to be called from the runtime to decode the llvm::Constants 117ea125c27974135fbad6bcb75b720499c68d52357A. Unique TensorFlower// that are created via ConvertShapeToSelfDescribingConstant and subsequently 118ea125c27974135fbad6bcb75b720499c68d52357A. Unique TensorFlower// embedded into the program. 119ea125c27974135fbad6bcb75b720499c68d52357A. Unique TensorFlowerStatusOr<Shape> DecodeSelfDescribingShapeConstant(const void* shape_ptr, 120ea125c27974135fbad6bcb75b720499c68d52357A. Unique TensorFlower int32 size_bytes); 121ea125c27974135fbad6bcb75b720499c68d52357A. Unique TensorFlower 1221e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Converts a given literal to an IR Constant. Literals have known constant 1231e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// values at IR emission time. 1241e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsllvm::Constant* ConvertLiteralToIrConstant(const Literal& literal, 1251e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::IRBuilder<>* ir_builder); 1261e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 1271e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Inserts an allocate of the requested type at the entry point of the 1281e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// function that the builder is currently building. The insert point 1291e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// of the builder is set to the same place after calling this function 1301e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// as before. 1311e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// 1321e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// This can be useful to avoid e.g. executing an alloca every time 1331e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// through a loop. 1341e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsllvm::AllocaInst* EmitAllocaAtFunctionEntry(llvm::Type* type, 1351e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins tensorflow::StringPiece name, 1361e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::IRBuilder<>* ir_builder, 1371e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins int alignment = 0); 1381e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 1391e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// As EmitAllocaAtFunctionEntry, but allocates element_count entries 1401e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// intead of a single element. 1411e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsllvm::AllocaInst* EmitAllocaAtFunctionEntryWithCount( 1421e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::Type* type, llvm::Value* element_count, tensorflow::StringPiece name, 1431e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::IRBuilder<>* ir_builder, int alignment = 0); 1441e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 1451b5235fd897f7ea5cffc715300f67b4dc852fa27Jonathan Hseu// Creates a basic block with the same context and function as for the 1461e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// builder. Inserts at the end of the function if insert_before is 1471e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// null. 1481e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsllvm::BasicBlock* CreateBasicBlock(llvm::BasicBlock* insert_before, 1491e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins tensorflow::StringPiece name, 1501e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::IRBuilder<>* ir_builder); 1511e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 1521e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Struct with data on a conditional branch in a diamond shape created 1531e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// via EmitIfThenElse. 1541e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsstruct LlvmIfData { 1551e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins // The block that has the conditional branch. 1561e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::BasicBlock* if_block; 1571e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 1581e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins // The block that is executed if the condition is true. 1591e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::BasicBlock* true_block; 1601e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 1611e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins // The block that is executed if the condition is false. 1621e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::BasicBlock* false_block; 1631e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 1641e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins // The block that follows after both the true_block and the 1651e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins // false_block. 1661e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::BasicBlock* after_block; 1671e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins}; 1681e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 1691e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Inserts a diamond-shaped if-then-else construct at the current 1701e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// insertion point of the builder. This involves splitting the current 1711e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// block into two blocks, at the insertion point, and introducing a 1721e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// true-block and a false-block that connect the two split pieces. The 1731e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// true-block is executed if the condition parameter evaluates to true 1741e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// and otherwise the false-block is executed. If `emit_else` is false, 1751e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// it jumps to the after-block rather than the false-block if the 1761e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// condition is false, and the returned `false_block` is null. 1771e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// 1781e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Currently the insertion point of the builder must be a well-formed 1791e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// block with a terminator. If you need to use this for a 1801e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// non-terminated block, just make the function able to do that too. 1811e67c90e2caceeff82d09793d1ef5fa0300d219bPeter HawkinsLlvmIfData EmitIfThenElse(llvm::Value* condition, tensorflow::StringPiece name, 1821e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::IRBuilder<>* ir_builder, bool emit_else = true); 1831e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 1841e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Emits a compare operation between "lhs" and "rhs" with the given predicate, 1851e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// and then converts the result to i8 so that it is addressable. 1861e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsllvm::Value* EmitComparison(llvm::CmpInst::Predicate predicate, 1871e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::Value* lhs, llvm::Value* rhs, 1881e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::IRBuilder<>* ir_builder); 1891e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 1901e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Emits a call that logs the given value with the given tag as a prefix. 1911e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// The provided tag and value are passed to a runtime logging call that is 1921e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// embedded in this translation unit when the emitted code is executed. 1931e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// 1941e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// This can be very useful for debugging generated programs in short order when 1951e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// developing new generated routines. 1961e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// 1971e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Precondition: value must be an int64. 1981e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Precondition: tag must be a stable pointer for the lifetime of the generated 1991e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// program (the constant pointer is burned in to the program). 2001e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsvoid EmitLogging(const char* tag, llvm::Value* value, 2011e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::IRBuilder<>* ir_builder); 2021e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 2031e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Adds TBAA metadata to a load or store instruction using the given shape as 2041e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// it's type. The is_pointer_to parameter is used to indicate whether or not 2051e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// this instruction loads or stores a pointer to an array. 2061e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsvoid SetTbaaForInstruction(llvm::Instruction* instruction, Shape shape, 2071e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins bool is_pointer_to); 2081e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 2091e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Adds alignment metadata to a load instruction using the given alignment. 2101e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// The alignment refers to the result of the load, not the load itself. 2111e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsvoid SetAlignmentMetadataForLoad(llvm::LoadInst* load, uint64_t alignment); 2121e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 2131e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Adds dereferenceable metadata to a load instruction using the given 2141e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// the number of dereferenceable bytes. 2151e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Dereferenceable refers to the result of the load, not the load itself. 2161e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsvoid SetDereferenceableMetadataForLoad(llvm::LoadInst* load, 2171e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins uint64_t dereferenceable_bytes); 2181e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 2191e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Tells LLVM `inst >= lower && inst < upper`. Returns `inst` for convenience. 2201e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsllvm::Instruction* AddRangeMetadata(int64 lower, int64 upper, 2211e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::Instruction* inst); 2221e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 2231e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsvoid SetToFirstInsertPoint(llvm::BasicBlock* blk, llvm::IRBuilder<>* builder); 2241e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 2251e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Create a bitwise rotation of `rotand` by `rotor`. 2261e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsllvm::Value* CreateRor(llvm::Value* rotand, llvm::Value* rotor, 2271e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins llvm::IRBuilder<>* builder); 2281e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 2291e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins// Returns the number of bytes within the shape. 2301e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkinsint64 ByteSizeOf(const Shape& shape, const llvm::DataLayout& data_layout); 2311e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 232d45505fe0c7ab9a10f16682f54d0eb54c4776cd1Justin Lebar// Gets an llvm::FastMathFlags that reflects the settings in the given 2337754ec45dc38e0f9cd047948045646418caad305Justin Lebar// module config. 234abbb19bb9445ffee96ff2946083a3b5c8dadc0d0Eli Benderskyllvm::FastMathFlags GetFastMathFlags(bool fast_math_enabled); 2351e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 236d45505fe0c7ab9a10f16682f54d0eb54c4776cd1Justin Lebar// Sets values in the given TargetOptions struct according to the given 237d45505fe0c7ab9a10f16682f54d0eb54c4776cd1Justin Lebar// compilation options. 238abbb19bb9445ffee96ff2946083a3b5c8dadc0d0Eli Benderskyvoid SetTargetOptions(bool fast_math_enabled, 239d45505fe0c7ab9a10f16682f54d0eb54c4776cd1Justin Lebar llvm::TargetOptions* target_options); 2401e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 2411e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins} // namespace llvm_ir 2421e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins} // namespace xla 2431e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins 2441e67c90e2caceeff82d09793d1ef5fa0300d219bPeter Hawkins#endif // TENSORFLOW_COMPILER_XLA_SERVICE_LLVM_IR_LLVM_UTIL_H_ 245