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   Builder.CreateCall(F, Constant::getNullValue(Builder.getInt8PtrTy()));
47 }
48 
49 void RuntimeDebugBuilder::createStrPrinter(PollyIRBuilder &Builder,
50                                            const std::string &String) {
51   Value *StringValue = Builder.CreateGlobalStringPtr(String);
52   Builder.CreateCall(getPrintF(Builder), StringValue);
53 
54   createFlush(Builder);
55 }
56 
57 void RuntimeDebugBuilder::createValuePrinter(PollyIRBuilder &Builder,
58                                              Value *V) {
59   const char *Format = nullptr;
60 
61   Type *Ty = V->getType();
62   if (Ty->isIntegerTy())
63     Format = "%ld";
64   else if (Ty->isFloatingPointTy())
65     Format = "%lf";
66   else if (Ty->isPointerTy())
67     Format = "%p";
68 
69   assert(Format && Ty->getPrimitiveSizeInBits() <= 64 && "Bad type to print.");
70 
71   Value *FormatString = Builder.CreateGlobalStringPtr(Format);
72   Builder.CreateCall2(getPrintF(Builder), FormatString, V);
73   createFlush(Builder);
74 }
75