mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-14 23:10:54 +00:00
![Tobias Grosser](/assets/img/avatar_default.png)
When our RuntimeDebugBuilder calles fflush(NULL) to flush all output streams, it is important that the types we use in the call match the ones used in a declaration of fflush possible already available in the translation unit. As we just pass on a NULL pointer, the type of the pointer value does not really matter. However, as LLVM complains in case of mismatched types, we make sure to create a NULL pointer of identical type. No test case, as RuntimeDebugBuilder is not permanently used in Polly. Calls to it are until now only used to add informative output during debugging sessions. llvm-svn: 221251
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);
|
|
}
|