Polly 20.0.0git
RuntimeDebugBuilder.cpp
Go to the documentation of this file.
1//===--- RuntimeDebugBuilder.cpp - Helper to insert prints into LLVM-IR ---===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//===----------------------------------------------------------------------===//
10
12#include "llvm/IR/Module.h"
13#include <string>
14#include <vector>
15
16using namespace llvm;
17using namespace polly;
18
20 llvm::StringRef Str) {
21 // FIXME: addressspace(4) is a marker for a string (for the %s conversion
22 // specifier) but should be using the default address space. This only works
23 // because CPU backends typically ignore the address space. For constant
24 // strings as returned by getPrintableString, the format string should instead
25 // directly spell out the string.
26 return Builder.CreateGlobalStringPtr(Str, "", 4);
27}
28
30 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
31 const char *Name = "vprintf";
32 Function *F = M->getFunction(Name);
33
34 if (!F) {
35 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
36 FunctionType *Ty = FunctionType::get(
37 Builder.getInt32Ty(), {Builder.getPtrTy(), Builder.getPtrTy()}, false);
38 F = Function::Create(Ty, Linkage, Name, M);
39 }
40
41 return F;
42}
43
45 ArrayRef<Value *> Values) {
46 createCPUPrinterT(Builder, Values);
47}
48
50 if (Ty->isFloatingPointTy())
51 return true;
52
53 if (Ty->isIntegerTy())
54 return Ty->getIntegerBitWidth() <= 64;
55
56 if (isa<PointerType>(Ty))
57 return true;
58
59 return false;
60}
61
62static std::tuple<std::string, std::vector<Value *>>
63prepareValuesForPrinting(PollyIRBuilder &Builder, ArrayRef<Value *> Values) {
64 std::string FormatString;
65 std::vector<Value *> ValuesToPrint;
66
67 for (auto Val : Values) {
68 Type *Ty = Val->getType();
69
70 if (Ty->isFloatingPointTy()) {
71 if (!Ty->isDoubleTy())
72 Val = Builder.CreateFPExt(Val, Builder.getDoubleTy());
73 } else if (Ty->isIntegerTy()) {
74 if (Ty->getIntegerBitWidth() < 64)
75 Val = Builder.CreateSExt(Val, Builder.getInt64Ty());
76 else
77 assert(Ty->getIntegerBitWidth() &&
78 "Integer types larger 64 bit not supported");
79 } else if (isa<PointerType>(Ty)) {
80 if (Ty == Builder.getPtrTy(4)) {
81 Val = Builder.CreateGEP(Builder.getInt8Ty(), Val, Builder.getInt64(0));
82 } else {
83 Val = Builder.CreatePtrToInt(Val, Builder.getInt64Ty());
84 }
85 } else {
86 llvm_unreachable("Unknown type");
87 }
88
89 Ty = Val->getType();
90
91 if (Ty->isFloatingPointTy())
92 FormatString += "%f";
93 else if (Ty->isIntegerTy())
94 FormatString += "%ld";
95 else
96 FormatString += "%s";
97
98 ValuesToPrint.push_back(Val);
99 }
100
101 return std::make_tuple(FormatString, ValuesToPrint);
102}
103
105 ArrayRef<Value *> Values) {
106
107 std::string FormatString;
108 std::vector<Value *> ValuesToPrint;
109
110 std::tie(FormatString, ValuesToPrint) =
111 prepareValuesForPrinting(Builder, Values);
112
113 createPrintF(Builder, FormatString, ValuesToPrint);
114 createFlush(Builder);
115}
116
118 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
119 const char *Name = "printf";
120 Function *F = M->getFunction(Name);
121
122 if (!F) {
123 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
124 FunctionType *Ty = FunctionType::get(Builder.getInt32Ty(), true);
125 F = Function::Create(Ty, Linkage, Name, M);
126 }
127
128 return F;
129}
130
132 std::string Format,
133 ArrayRef<Value *> Values) {
134 Value *FormatString = Builder.CreateGlobalStringPtr(Format);
135 std::vector<Value *> Arguments;
136
137 Arguments.push_back(FormatString);
138 Arguments.insert(Arguments.end(), Values.begin(), Values.end());
139 Builder.CreateCall(getPrintF(Builder), Arguments);
140}
141
143 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
144 const char *Name = "fflush";
145 Function *F = M->getFunction(Name);
146
147 if (!F) {
148 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
149 FunctionType *Ty =
150 FunctionType::get(Builder.getInt32Ty(), Builder.getPtrTy(), false);
151 F = Function::Create(Ty, Linkage, Name, M);
152 }
153
154 // fflush(NULL) flushes _all_ open output streams.
155 //
156 // fflush is declared as 'int fflush(FILE *stream)'. As we only pass on a NULL
157 // pointer, the type we point to does conceptually not matter. However, if
158 // fflush is already declared in this translation unit, we use the very same
159 // type to ensure that LLVM does not complain about mismatching types.
160 Builder.CreateCall(F, Constant::getNullValue(F->arg_begin()->getType()));
161}
polly dump Polly Dump Function
polly dump Polly Dump Module
static std::tuple< std::string, std::vector< Value * > > prepareValuesForPrinting(PollyIRBuilder &Builder, ArrayRef< Value * > Values)
static RegisterPass< ScopPrinterWrapperPass > M("dot-scops", "Polly - Print Scops of function")
#define assert(exp)
This file contains the declaration of the PolyhedralInfo class, which will provide an interface to ex...
@ Value
MemoryKind::Value: Models an llvm::Value.
llvm::IRBuilder< llvm::ConstantFolder, IRInserter > PollyIRBuilder
Definition: IRBuilder.h:140
static void createCPUPrinterT(PollyIRBuilder &Builder, llvm::ArrayRef< llvm::Value * > Values)
Print a list of Values on a CPU.
static void createPrinter(PollyIRBuilder &Builder, std::vector< llvm::Value * > &Values, llvm::Value *Value, Args... args)
Handle Values.
static void createFlush(PollyIRBuilder &Builder)
Call fflush.
static llvm::Function * getPrintF(PollyIRBuilder &Builder)
Get a reference to the 'printf' function.
static void createPrintF(PollyIRBuilder &Builder, std::string Format, llvm::ArrayRef< llvm::Value * > Values)
Call printf.
static llvm::Function * getVPrintF(PollyIRBuilder &Builder)
Get (and possibly insert) a vprintf declaration into the module.
static bool isPrintable(llvm::Type *Ty)
Return whether an llvm::Value of the type Ty is printable for debugging.
static llvm::Value * getPrintableString(PollyIRBuilder &Builder, llvm::StringRef Str)
Generate a constant string into the builder's llvm::Module which can be passed to createCPUPrinter().
static TupleKindPtr Str