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)
|
||||
fixup_D(arg);
|
||||
|
||||
#if 0
|
||||
// These can get pretty large...
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "New arg type: " << *arg.ltype << '\n';
|
||||
#endif
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -735,10 +732,8 @@ void X86_64TargetABI::rewriteFunctionType(TypeFunction* tf) {
|
|||
Type* ty = arg.type->toBasetype();
|
||||
|
||||
fixup(arg);
|
||||
#if 0
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "New arg type: " << *arg.ltype << '\n';
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -385,10 +385,8 @@ struct IntrinsicABI : TargetABI
|
|||
if (ty->ty == Tstruct)
|
||||
fixup(arg);
|
||||
|
||||
#if 0
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "New arg type: " << *arg.ltype << '\n';
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -721,7 +721,7 @@ void AsmBlockStatement::toIR(IRState* p)
|
|||
Logger::cout() << "Arguments:" << '\n';
|
||||
Logger::indent();
|
||||
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;
|
||||
if (!llvm::isa<llvm::Instruction>(*i) && !llvm::isa<LLGlobalValue>(*i))
|
||||
cout << '\n';
|
||||
|
|
|
@ -491,9 +491,7 @@ LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd)
|
|||
{
|
||||
Logger::cout() << "src2: " << *src << '\n';
|
||||
Logger::cout() << "index: " << field->index << '\n';
|
||||
#if 0
|
||||
Logger::cout() << "srctype: " << *src->getType() << '\n';
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
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);
|
||||
|
||||
#if 0
|
||||
Logger::cout() << "Final function type: " << *functype << "\n";
|
||||
#endif
|
||||
|
||||
return functype;
|
||||
}
|
||||
|
|
|
@ -329,7 +329,7 @@ int linkObjToExecutable(const char* argv0)
|
|||
|
||||
Logger::println("Linking with: ");
|
||||
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)
|
||||
if (*I)
|
||||
logstr << "'" << *I << "'" << " ";
|
||||
|
|
|
@ -4,11 +4,34 @@
|
|||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "mars.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/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
|
||||
{
|
||||
|
@ -31,10 +54,10 @@ namespace Logger
|
|||
indent_str.resize(indent_str.size()-2);
|
||||
}
|
||||
}
|
||||
llvm::OStream cout()
|
||||
Stream cout()
|
||||
{
|
||||
if (_enabled)
|
||||
return llvm::cout << indent_str;
|
||||
return std::cout << indent_str;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
|
67
gen/logger.h
67
gen/logger.h
|
@ -1,7 +1,12 @@
|
|||
#ifndef _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
|
||||
# ifdef __GNUC__
|
||||
|
@ -13,11 +18,69 @@
|
|||
|
||||
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
|
||||
{
|
||||
void indent();
|
||||
void undent();
|
||||
llvm::OStream cout();
|
||||
Stream cout();
|
||||
void println(const char* fmt, ...) IS_PRINTF(1);
|
||||
void print(const char* fmt, ...) IS_PRINTF(1);
|
||||
void enable();
|
||||
|
|
|
@ -385,7 +385,7 @@ void assemble(const llvm::sys::Path& asmpath, const llvm::sys::Path& objpath)
|
|||
if (Logger::enabled()) {
|
||||
Logger::println("Assembling with: ");
|
||||
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)
|
||||
if (*I)
|
||||
logstr << "'" << *I << "'" << " ";
|
||||
|
|
|
@ -281,9 +281,7 @@ const llvm::Type* IrTypeClass::buildType()
|
|||
name.append(".__vtbl");
|
||||
Type::sir->getState()->module->addTypeName(name, vtbl_pa.get());
|
||||
|
||||
#if 0
|
||||
IF_LOG Logger::cout() << "class type: " << *pa.get() << std::endl;
|
||||
#endif
|
||||
|
||||
return get();
|
||||
}
|
||||
|
|
|
@ -227,9 +227,7 @@ const llvm::Type* IrTypeStruct::buildType()
|
|||
// name types
|
||||
Type::sir->getState()->module->addTypeName(sd->toPrettyChars(), pa.get());
|
||||
|
||||
#if 0
|
||||
IF_LOG Logger::cout() << "final struct type: " << *pa.get() << std::endl;
|
||||
#endif
|
||||
|
||||
return pa.get();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue