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