[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / polly / lib / CodeGen / RuntimeDebugBuilder.cpp
blobfe30924c028629045853c3dc4259bcc93757c458
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 //===----------------------------------------------------------------------===//
11 #include "polly/CodeGen/RuntimeDebugBuilder.h"
12 #include "llvm/IR/Module.h"
13 #include <string>
14 #include <vector>
16 using namespace llvm;
17 using namespace polly;
19 llvm::Value *RuntimeDebugBuilder::getPrintableString(PollyIRBuilder &Builder,
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);
29 Function *RuntimeDebugBuilder::getVPrintF(PollyIRBuilder &Builder) {
30 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
31 const char *Name = "vprintf";
32 Function *F = M->getFunction(Name);
34 if (!F) {
35 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
36 FunctionType *Ty = FunctionType::get(
37 Builder.getInt32Ty(), {Builder.getInt8PtrTy(), Builder.getInt8PtrTy()},
38 false);
39 F = Function::Create(Ty, Linkage, Name, M);
42 return F;
45 void RuntimeDebugBuilder::createPrinter(PollyIRBuilder &Builder,
46 ArrayRef<Value *> Values) {
47 createCPUPrinterT(Builder, Values);
50 bool RuntimeDebugBuilder::isPrintable(Type *Ty) {
51 if (Ty->isFloatingPointTy())
52 return true;
54 if (Ty->isIntegerTy())
55 return Ty->getIntegerBitWidth() <= 64;
57 if (isa<PointerType>(Ty))
58 return true;
60 return false;
63 static std::tuple<std::string, std::vector<Value *>>
64 prepareValuesForPrinting(PollyIRBuilder &Builder, ArrayRef<Value *> Values) {
65 std::string FormatString;
66 std::vector<Value *> ValuesToPrint;
68 for (auto Val : Values) {
69 Type *Ty = Val->getType();
71 if (Ty->isFloatingPointTy()) {
72 if (!Ty->isDoubleTy())
73 Val = Builder.CreateFPExt(Val, Builder.getDoubleTy());
74 } else if (Ty->isIntegerTy()) {
75 if (Ty->getIntegerBitWidth() < 64)
76 Val = Builder.CreateSExt(Val, Builder.getInt64Ty());
77 else
78 assert(Ty->getIntegerBitWidth() &&
79 "Integer types larger 64 bit not supported");
80 } else if (isa<PointerType>(Ty)) {
81 if (Ty == Builder.getInt8PtrTy(4)) {
82 Val = Builder.CreateGEP(Builder.getInt8Ty(), Val, Builder.getInt64(0));
83 } else {
84 Val = Builder.CreatePtrToInt(Val, Builder.getInt64Ty());
86 } else {
87 llvm_unreachable("Unknown type");
90 Ty = Val->getType();
92 if (Ty->isFloatingPointTy())
93 FormatString += "%f";
94 else if (Ty->isIntegerTy())
95 FormatString += "%ld";
96 else
97 FormatString += "%s";
99 ValuesToPrint.push_back(Val);
102 return std::make_tuple(FormatString, ValuesToPrint);
105 void RuntimeDebugBuilder::createCPUPrinterT(PollyIRBuilder &Builder,
106 ArrayRef<Value *> Values) {
108 std::string FormatString;
109 std::vector<Value *> ValuesToPrint;
111 std::tie(FormatString, ValuesToPrint) =
112 prepareValuesForPrinting(Builder, Values);
114 createPrintF(Builder, FormatString, ValuesToPrint);
115 createFlush(Builder);
118 Function *RuntimeDebugBuilder::getPrintF(PollyIRBuilder &Builder) {
119 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
120 const char *Name = "printf";
121 Function *F = M->getFunction(Name);
123 if (!F) {
124 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
125 FunctionType *Ty = FunctionType::get(Builder.getInt32Ty(), true);
126 F = Function::Create(Ty, Linkage, Name, M);
129 return F;
132 void RuntimeDebugBuilder::createPrintF(PollyIRBuilder &Builder,
133 std::string Format,
134 ArrayRef<Value *> Values) {
135 Value *FormatString = Builder.CreateGlobalStringPtr(Format);
136 std::vector<Value *> Arguments;
138 Arguments.push_back(FormatString);
139 Arguments.insert(Arguments.end(), Values.begin(), Values.end());
140 Builder.CreateCall(getPrintF(Builder), Arguments);
143 void RuntimeDebugBuilder::createFlush(PollyIRBuilder &Builder) {
144 Module *M = Builder.GetInsertBlock()->getParent()->getParent();
145 const char *Name = "fflush";
146 Function *F = M->getFunction(Name);
148 if (!F) {
149 GlobalValue::LinkageTypes Linkage = Function::ExternalLinkage;
150 FunctionType *Ty =
151 FunctionType::get(Builder.getInt32Ty(), Builder.getInt8PtrTy(), false);
152 F = Function::Create(Ty, Linkage, Name, M);
155 // fflush(NULL) flushes _all_ open output streams.
157 // fflush is declared as 'int fflush(FILE *stream)'. As we only pass on a NULL
158 // pointer, the type we point to does conceptually not matter. However, if
159 // fflush is already declared in this translation unit, we use the very same
160 // type to ensure that LLVM does not complain about mismatching types.
161 Builder.CreateCall(F, Constant::getNullValue(F->arg_begin()->getType()));