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 14 #include "llvm/IR/Module.h" 15 16 using namespace llvm; 17 using namespace polly; 18 19 Function *RuntimeDebugBuilder::getPrintF(PollyIRBuilder &Builder) { 20 Module *M = Builder.GetInsertBlock()->getParent()->getParent(); 21 const char *Name = "printf"; 22 Function *F = M->getFunction(Name); 23 24 if (!F) { 25 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage; 26 FunctionType *Ty = 27 FunctionType::get(Builder.getInt32Ty(), Builder.getInt8PtrTy(), true); 28 F = Function::Create(Ty, Linkage, Name, M); 29 } 30 31 return F; 32 } 33 34 void RuntimeDebugBuilder::createFlush(PollyIRBuilder &Builder) { 35 Module *M = Builder.GetInsertBlock()->getParent()->getParent(); 36 const char *Name = "fflush"; 37 Function *F = M->getFunction(Name); 38 39 if (!F) { 40 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage; 41 FunctionType *Ty = 42 FunctionType::get(Builder.getInt32Ty(), Builder.getInt8PtrTy(), false); 43 F = Function::Create(Ty, Linkage, Name, M); 44 } 45 46 // fflush(NULL) flushes _all_ open output streams. 47 // 48 // fflush is declared as 'int fflush(FILE *stream)'. As we only pass on a NULL 49 // pointer, the type we point to does conceptually not matter. However, if 50 // fflush is already declared in this translation unit, we use the very same 51 // type to ensure that LLVM does not complain about mismatching types. 52 Builder.CreateCall(F, Constant::getNullValue(F->arg_begin()->getType())); 53 } 54 55 void RuntimeDebugBuilder::createStrPrinter(PollyIRBuilder &Builder, 56 const std::string &String) { 57 Value *StringValue = Builder.CreateGlobalStringPtr(String); 58 Builder.CreateCall(getPrintF(Builder), StringValue); 59 60 createFlush(Builder); 61 } 62 63 void RuntimeDebugBuilder::createValuePrinter(PollyIRBuilder &Builder, 64 Value *V) { 65 const char *Format = nullptr; 66 67 Type *Ty = V->getType(); 68 if (Ty->isIntegerTy()) 69 Format = "%ld"; 70 else if (Ty->isFloatingPointTy()) 71 Format = "%lf"; 72 else if (Ty->isPointerTy()) 73 Format = "%p"; 74 75 assert(Format && Ty->getPrimitiveSizeInBits() <= 64 && "Bad type to print."); 76 77 Value *FormatString = Builder.CreateGlobalStringPtr(Format); 78 Builder.CreateCall2(getPrintF(Builder), FormatString, V); 79 createFlush(Builder); 80 } 81