forked from OSchip/llvm-project
81 lines
2.7 KiB
C++
81 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);
|
|
}
|