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:
Frits van Bommel 2009-06-16 19:31:10 +02:00
parent 348192e7e7
commit 4158fb474a
11 changed files with 93 additions and 22 deletions

View file

@ -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
} }
} }
} }

View file

@ -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
} }
} }
}; };

View file

@ -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';

View file

@ -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);

View file

@ -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;
} }

View file

@ -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 << "'" << " ";

View file

@ -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;
} }

View file

@ -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();

View file

@ -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 << "'" << " ";

View file

@ -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();
} }

View file

@ -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();
} }