mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 09:00:33 +03:00
Add an llvm::OStream
workalike class for use with Logger::cout()
, with the
crucial difference being special handling of `llvm::Type`s so they get printed by name rather than printing their full representation (which can be positively *huge*). This allows re-enabling some logger calls that were disabled due to extreme verbosity.
This commit is contained in:
parent
348192e7e7
commit
4158fb474a
11 changed files with 93 additions and 22 deletions
|
@ -701,11 +701,8 @@ void X86_64TargetABI::rewriteFunctionType(TypeFunction* tf) {
|
||||||
if (ty->ty == Tstruct)
|
if (ty->ty == Tstruct)
|
||||||
fixup_D(arg);
|
fixup_D(arg);
|
||||||
|
|
||||||
#if 0
|
|
||||||
// These can get pretty large...
|
|
||||||
if (Logger::enabled())
|
if (Logger::enabled())
|
||||||
Logger::cout() << "New arg type: " << *arg.ltype << '\n';
|
Logger::cout() << "New arg type: " << *arg.ltype << '\n';
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -735,10 +732,8 @@ void X86_64TargetABI::rewriteFunctionType(TypeFunction* tf) {
|
||||||
Type* ty = arg.type->toBasetype();
|
Type* ty = arg.type->toBasetype();
|
||||||
|
|
||||||
fixup(arg);
|
fixup(arg);
|
||||||
#if 0
|
|
||||||
if (Logger::enabled())
|
if (Logger::enabled())
|
||||||
Logger::cout() << "New arg type: " << *arg.ltype << '\n';
|
Logger::cout() << "New arg type: " << *arg.ltype << '\n';
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,10 +385,8 @@ struct IntrinsicABI : TargetABI
|
||||||
if (ty->ty == Tstruct)
|
if (ty->ty == Tstruct)
|
||||||
fixup(arg);
|
fixup(arg);
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (Logger::enabled())
|
if (Logger::enabled())
|
||||||
Logger::cout() << "New arg type: " << *arg.ltype << '\n';
|
Logger::cout() << "New arg type: " << *arg.ltype << '\n';
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -721,7 +721,7 @@ void AsmBlockStatement::toIR(IRState* p)
|
||||||
Logger::cout() << "Arguments:" << '\n';
|
Logger::cout() << "Arguments:" << '\n';
|
||||||
Logger::indent();
|
Logger::indent();
|
||||||
for (std::vector<LLValue*>::iterator b = args.begin(), i = b, e = args.end(); i != e; ++i) {
|
for (std::vector<LLValue*>::iterator b = args.begin(), i = b, e = args.end(); i != e; ++i) {
|
||||||
llvm::OStream cout = Logger::cout();
|
Stream cout = Logger::cout();
|
||||||
cout << '$' << (i - b) << " ==> " << **i;
|
cout << '$' << (i - b) << " ==> " << **i;
|
||||||
if (!llvm::isa<llvm::Instruction>(*i) && !llvm::isa<LLGlobalValue>(*i))
|
if (!llvm::isa<llvm::Instruction>(*i) && !llvm::isa<LLGlobalValue>(*i))
|
||||||
cout << '\n';
|
cout << '\n';
|
||||||
|
|
|
@ -491,9 +491,7 @@ LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd)
|
||||||
{
|
{
|
||||||
Logger::cout() << "src2: " << *src << '\n';
|
Logger::cout() << "src2: " << *src << '\n';
|
||||||
Logger::cout() << "index: " << field->index << '\n';
|
Logger::cout() << "index: " << field->index << '\n';
|
||||||
#if 0
|
|
||||||
Logger::cout() << "srctype: " << *src->getType() << '\n';
|
Logger::cout() << "srctype: " << *src->getType() << '\n';
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
LLValue* val = DtoGEPi(src, 0, field->index);
|
LLValue* val = DtoGEPi(src, 0, field->index);
|
||||||
|
|
|
@ -194,9 +194,7 @@ const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nest
|
||||||
|
|
||||||
llvm::FunctionType* functype = llvm::FunctionType::get(f->fty.ret->ltype, argtypes, f->fty.c_vararg);
|
llvm::FunctionType* functype = llvm::FunctionType::get(f->fty.ret->ltype, argtypes, f->fty.c_vararg);
|
||||||
|
|
||||||
#if 0
|
|
||||||
Logger::cout() << "Final function type: " << *functype << "\n";
|
Logger::cout() << "Final function type: " << *functype << "\n";
|
||||||
#endif
|
|
||||||
|
|
||||||
return functype;
|
return functype;
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,7 +329,7 @@ int linkObjToExecutable(const char* argv0)
|
||||||
|
|
||||||
Logger::println("Linking with: ");
|
Logger::println("Linking with: ");
|
||||||
std::vector<const char*>::const_iterator I = args.begin(), E = args.end();
|
std::vector<const char*>::const_iterator I = args.begin(), E = args.end();
|
||||||
llvm::OStream logstr = Logger::cout();
|
Stream logstr = Logger::cout();
|
||||||
for (; I != E; ++I)
|
for (; I != E; ++I)
|
||||||
if (*I)
|
if (*I)
|
||||||
logstr << "'" << *I << "'" << " ";
|
logstr << "'" << *I << "'" << " ";
|
||||||
|
|
|
@ -4,11 +4,34 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "mars.h"
|
#include "mars.h"
|
||||||
|
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
|
||||||
|
#include "llvm/GlobalValue.h"
|
||||||
|
#include "llvm/Support/Casting.h"
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#include "llvm/Assembly/Writer.h"
|
||||||
|
|
||||||
#include "gen/logger.h"
|
#include "gen/logger.h"
|
||||||
|
#include "gen/irstate.h"
|
||||||
|
|
||||||
|
void Stream::writeType(std::ostream& OS, const llvm::Type& Ty) {
|
||||||
|
llvm::raw_os_ostream raw(OS);
|
||||||
|
llvm::WriteTypeSymbolic(raw, &Ty, gIR->module);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stream::writeValue(std::ostream& OS, const llvm::Value& V) {
|
||||||
|
// Constants don't always get their types pretty-printed.
|
||||||
|
// (Only treat non-global constants like this, so that e.g. global variables
|
||||||
|
// still get their initializers printed)
|
||||||
|
if (llvm::isa<llvm::Constant>(V) && !llvm::isa<llvm::GlobalValue>(V))
|
||||||
|
llvm::WriteAsOperand(OS, &V, true, gIR->module);
|
||||||
|
else
|
||||||
|
OS << V;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Logger
|
namespace Logger
|
||||||
{
|
{
|
||||||
|
@ -31,10 +54,10 @@ namespace Logger
|
||||||
indent_str.resize(indent_str.size()-2);
|
indent_str.resize(indent_str.size()-2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
llvm::OStream cout()
|
Stream cout()
|
||||||
{
|
{
|
||||||
if (_enabled)
|
if (_enabled)
|
||||||
return llvm::cout << indent_str;
|
return std::cout << indent_str;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
67
gen/logger.h
67
gen/logger.h
|
@ -1,7 +1,12 @@
|
||||||
#ifndef _llvmd_gen_logger_h_
|
#ifndef _llvmd_gen_logger_h_
|
||||||
#define _llvmd_gen_logger_h_
|
#define _llvmd_gen_logger_h_
|
||||||
|
|
||||||
#include "llvm/Support/Streams.h"
|
#include <iosfwd>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
class Type;
|
||||||
|
class Value;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef IS_PRINTF
|
#ifndef IS_PRINTF
|
||||||
# ifdef __GNUC__
|
# ifdef __GNUC__
|
||||||
|
@ -13,11 +18,69 @@
|
||||||
|
|
||||||
struct Loc;
|
struct Loc;
|
||||||
|
|
||||||
|
class Stream {
|
||||||
|
std::ostream* OS;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Stream() : OS(0) {}
|
||||||
|
Stream(std::ostream* S) : OS(S) {}
|
||||||
|
Stream(std::ostream& S) : OS(&S) {}
|
||||||
|
|
||||||
|
Stream operator << (std::ios_base &(*Func)(std::ios_base&)) {
|
||||||
|
if (OS) *OS << Func;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream operator << (std::ostream &(*Func)(std::ostream&)) {
|
||||||
|
if (OS) *OS << Func;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Ty>
|
||||||
|
Stream& operator << (const Ty& Thing) {
|
||||||
|
if (OS)
|
||||||
|
Writer<Ty, sizeof(sfinae_bait(Thing))>::write(*OS, Thing);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Implementation details to treat llvm::Value, llvm::Type and their
|
||||||
|
// subclasses specially (to pretty-print types).
|
||||||
|
|
||||||
|
static void writeType(std::ostream& OS, const llvm::Type& Ty);
|
||||||
|
static void writeValue(std::ostream& OS, const llvm::Value& Ty);
|
||||||
|
|
||||||
|
template<typename Ty, int N> friend struct Writer;
|
||||||
|
// error: function template partial specialization is not allowed
|
||||||
|
// So I guess type partial specialization + member function will have to do...
|
||||||
|
template<typename Ty, int N>
|
||||||
|
struct Writer {
|
||||||
|
static void write(std::ostream& OS, const Ty& Thing) {
|
||||||
|
OS << Thing;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Ty>
|
||||||
|
struct Writer<Ty, 1> {
|
||||||
|
static void write(std::ostream& OS, const llvm::Type& Thing) {
|
||||||
|
Stream::writeType(OS, Thing);
|
||||||
|
}
|
||||||
|
static void write(std::ostream& OS, const llvm::Value& Thing) {
|
||||||
|
Stream::writeValue(OS, Thing);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// NOT IMPLEMENTED
|
||||||
|
char sfinae_bait(const llvm::Type&);
|
||||||
|
char sfinae_bait(const llvm::Value&);
|
||||||
|
short sfinae_bait(...);
|
||||||
|
};
|
||||||
|
|
||||||
namespace Logger
|
namespace Logger
|
||||||
{
|
{
|
||||||
void indent();
|
void indent();
|
||||||
void undent();
|
void undent();
|
||||||
llvm::OStream cout();
|
Stream cout();
|
||||||
void println(const char* fmt, ...) IS_PRINTF(1);
|
void println(const char* fmt, ...) IS_PRINTF(1);
|
||||||
void print(const char* fmt, ...) IS_PRINTF(1);
|
void print(const char* fmt, ...) IS_PRINTF(1);
|
||||||
void enable();
|
void enable();
|
||||||
|
|
|
@ -385,7 +385,7 @@ void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath)
|
||||||
if (Logger::enabled()) {
|
if (Logger::enabled()) {
|
||||||
Logger::println("Assembling with: ");
|
Logger::println("Assembling with: ");
|
||||||
std::vector<const char*>::const_iterator I = Args.begin(), E = Args.end();
|
std::vector<const char*>::const_iterator I = Args.begin(), E = Args.end();
|
||||||
std::ostream& logstr = *Logger::cout().stream();
|
Stream logstr = Logger::cout();
|
||||||
for (; I != E; ++I)
|
for (; I != E; ++I)
|
||||||
if (*I)
|
if (*I)
|
||||||
logstr << "'" << *I << "'" << " ";
|
logstr << "'" << *I << "'" << " ";
|
||||||
|
|
|
@ -281,9 +281,7 @@ const llvm::Type* IrTypeClass::buildType()
|
||||||
name.append(".__vtbl");
|
name.append(".__vtbl");
|
||||||
Type::sir->getState()->module->addTypeName(name, vtbl_pa.get());
|
Type::sir->getState()->module->addTypeName(name, vtbl_pa.get());
|
||||||
|
|
||||||
#if 0
|
|
||||||
IF_LOG Logger::cout() << "class type: " << *pa.get() << std::endl;
|
IF_LOG Logger::cout() << "class type: " << *pa.get() << std::endl;
|
||||||
#endif
|
|
||||||
|
|
||||||
return get();
|
return get();
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,9 +227,7 @@ const llvm::Type* IrTypeStruct::buildType()
|
||||||
// name types
|
// name types
|
||||||
Type::sir->getState()->module->addTypeName(sd->toPrettyChars(), pa.get());
|
Type::sir->getState()->module->addTypeName(sd->toPrettyChars(), pa.get());
|
||||||
|
|
||||||
#if 0
|
|
||||||
IF_LOG Logger::cout() << "final struct type: " << *pa.get() << std::endl;
|
IF_LOG Logger::cout() << "final struct type: " << *pa.get() << std::endl;
|
||||||
#endif
|
|
||||||
|
|
||||||
return pa.get();
|
return pa.get();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue