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