Upcoming revisions of isl require us to include header files explicitly, which have previously been already transitively included. Before we add them, we sort the existing includes. Thanks to Chandler for sort_includes.py. A simple, but very convenient script. llvm-svn: 236930
80 lines
2.7 KiB
C++
80 lines
2.7 KiB
C++
//===--- 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);
|
|
}
|