1 //===--- RuntimeDebugBuilder.cpp - Helper to insert prints into LLVM-IR ---===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 //===----------------------------------------------------------------------===// 11 12 #include "polly/CodeGen/RuntimeDebugBuilder.h" 13 #include "llvm/IR/Module.h" 14 #include "llvm/Support/Debug.h" 15 #include <string> 16 #include <vector> 17 18 using namespace llvm; 19 using namespace polly; 20 21 Function *RuntimeDebugBuilder::getVPrintF(PollyIRBuilder &Builder) { 22 Module *M = Builder.GetInsertBlock()->getParent()->getParent(); 23 const char *Name = "vprintf"; 24 Function *F = M->getFunction(Name); 25 26 if (!F) { 27 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage; 28 FunctionType *Ty = FunctionType::get( 29 Builder.getInt32Ty(), {Builder.getInt8PtrTy(), Builder.getInt8PtrTy()}, 30 false); 31 F = Function::Create(Ty, Linkage, Name, M); 32 } 33 34 return F; 35 } 36 37 Function *RuntimeDebugBuilder::getAddressSpaceCast(PollyIRBuilder &Builder, 38 unsigned Src, unsigned Dst, 39 unsigned SrcBits, 40 unsigned DstBits) { 41 Module *M = Builder.GetInsertBlock()->getParent()->getParent(); 42 auto Name = std::string("llvm.nvvm.ptr.constant.to.gen.p") + 43 std::to_string(Dst) + "i" + std::to_string(DstBits) + ".p" + 44 std::to_string(Src) + "i" + std::to_string(SrcBits); 45 Function *F = M->getFunction(Name); 46 47 if (!F) { 48 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage; 49 FunctionType *Ty = FunctionType::get( 50 PointerType::get(Builder.getIntNTy(DstBits), Dst), 51 PointerType::get(Builder.getIntNTy(SrcBits), Src), false); 52 F = Function::Create(Ty, Linkage, Name, M); 53 } 54 55 return F; 56 } 57 58 void RuntimeDebugBuilder::createGPUVAPrinter(PollyIRBuilder &Builder, 59 ArrayRef<Value *> Values) { 60 std::string str; 61 62 // Allocate print buffer (assuming 2*32 bit per element) 63 auto T = ArrayType::get(Builder.getInt32Ty(), Values.size() * 2); 64 Value *Data = new AllocaInst( 65 T, "polly.vprint.buffer", 66 Builder.GetInsertBlock()->getParent()->getEntryBlock().begin()); 67 68 auto *Zero = Builder.getInt64(0); 69 auto *DataPtr = Builder.CreateGEP(Data, {Zero, Zero}); 70 71 int Offset = 0; 72 for (auto Val : Values) { 73 auto Ptr = Builder.CreateGEP(DataPtr, {Builder.getInt64(Offset)}); 74 Type *Ty = Val->getType(); 75 76 if (Ty->isFloatingPointTy()) { 77 if (!Ty->isDoubleTy()) { 78 Ty = Builder.getDoubleTy(); 79 Val = Builder.CreateFPExt(Val, Ty); 80 } 81 } else if (Ty->isIntegerTy()) { 82 auto Int64Bitwidth = Builder.getInt64Ty()->getIntegerBitWidth(); 83 assert(Ty->getIntegerBitWidth() <= Int64Bitwidth); 84 if (Ty->getIntegerBitWidth() < Int64Bitwidth) { 85 Ty = Builder.getInt64Ty(); 86 Val = Builder.CreateSExt(Val, Ty); 87 } 88 } else { 89 // If it is not a number, it must be a string type. 90 Val = Builder.CreateGEP(Val, Builder.getInt64(0)); 91 assert((Val->getType() == Builder.getInt8PtrTy(4)) && 92 "Expected i8 ptr placed in constant address space"); 93 auto F = RuntimeDebugBuilder::getAddressSpaceCast(Builder, 4, 0); 94 Val = Builder.CreateCall(F, Val); 95 Ty = Val->getType(); 96 } 97 98 Ptr = Builder.CreatePointerBitCastOrAddrSpaceCast(Ptr, Ty->getPointerTo(5)); 99 Builder.CreateAlignedStore(Val, Ptr, 4); 100 101 if (Ty->isFloatingPointTy()) 102 str += "%f"; 103 else if (Ty->isIntegerTy()) 104 str += "%ld"; 105 else 106 str += "%s"; 107 108 Offset += 2; 109 } 110 111 Value *Format = Builder.CreateGlobalStringPtr(str, "polly.vprintf.buffer", 4); 112 Format = Builder.CreateCall(getAddressSpaceCast(Builder, 4, 0), Format); 113 114 Data = Builder.CreateBitCast(Data, Builder.getInt8PtrTy()); 115 116 Builder.CreateCall(getVPrintF(Builder), {Format, Data}); 117 } 118 119 Function *RuntimeDebugBuilder::getPrintF(PollyIRBuilder &Builder) { 120 Module *M = Builder.GetInsertBlock()->getParent()->getParent(); 121 const char *Name = "printf"; 122 Function *F = M->getFunction(Name); 123 124 if (!F) { 125 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage; 126 FunctionType *Ty = 127 FunctionType::get(Builder.getInt32Ty(), Builder.getInt8PtrTy(), true); 128 F = Function::Create(Ty, Linkage, Name, M); 129 } 130 131 return F; 132 } 133 134 void RuntimeDebugBuilder::createFlush(PollyIRBuilder &Builder) { 135 Module *M = Builder.GetInsertBlock()->getParent()->getParent(); 136 const char *Name = "fflush"; 137 Function *F = M->getFunction(Name); 138 139 if (!F) { 140 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage; 141 FunctionType *Ty = 142 FunctionType::get(Builder.getInt32Ty(), Builder.getInt8PtrTy(), false); 143 F = Function::Create(Ty, Linkage, Name, M); 144 } 145 146 // fflush(NULL) flushes _all_ open output streams. 147 // 148 // fflush is declared as 'int fflush(FILE *stream)'. As we only pass on a NULL 149 // pointer, the type we point to does conceptually not matter. However, if 150 // fflush is already declared in this translation unit, we use the very same 151 // type to ensure that LLVM does not complain about mismatching types. 152 Builder.CreateCall(F, Constant::getNullValue(F->arg_begin()->getType())); 153 } 154 155 void RuntimeDebugBuilder::createStrPrinter(PollyIRBuilder &Builder, 156 const std::string &String) { 157 Value *StringValue = Builder.CreateGlobalStringPtr(String); 158 Builder.CreateCall(getPrintF(Builder), StringValue); 159 160 createFlush(Builder); 161 } 162 163 void RuntimeDebugBuilder::createValuePrinter(PollyIRBuilder &Builder, 164 Value *V) { 165 const char *Format = nullptr; 166 167 Type *Ty = V->getType(); 168 if (Ty->isIntegerTy()) 169 Format = "%ld"; 170 else if (Ty->isFloatingPointTy()) 171 Format = "%lf"; 172 else if (Ty->isPointerTy()) 173 Format = "%p"; 174 175 assert(Format && Ty->getPrimitiveSizeInBits() <= 64 && "Bad type to print."); 176 177 Value *FormatString = Builder.CreateGlobalStringPtr(Format); 178 Builder.CreateCall(getPrintF(Builder), {FormatString, V}); 179 createFlush(Builder); 180 } 181