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