# HG changeset patch # User Robert Clipsham # Date 1245336258 -3600 # Node ID 1e5a14691e77843b8cd7c3d7b479e21ee39d0ab2 # Parent cc5fee7836dcd7e27d7e6179287b3812f2cf3481# Parent 855f188aab7ae46063713bc905418eda349933dc Automated merge with http://hg.dsource.org/projects/ldc diff -r 855f188aab7a -r 1e5a14691e77 gen/abi-x86-64.cpp --- a/gen/abi-x86-64.cpp Thu Jun 18 15:44:04 2009 +0100 +++ b/gen/abi-x86-64.cpp Thu Jun 18 15:44:18 2009 +0100 @@ -701,11 +701,8 @@ 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 @@ Type* ty = arg.type->toBasetype(); fixup(arg); -#if 0 if (Logger::enabled()) Logger::cout() << "New arg type: " << *arg.ltype << '\n'; -#endif } } } diff -r 855f188aab7a -r 1e5a14691e77 gen/abi.cpp --- a/gen/abi.cpp Thu Jun 18 15:44:04 2009 +0100 +++ b/gen/abi.cpp Thu Jun 18 15:44:18 2009 +0100 @@ -385,10 +385,8 @@ if (ty->ty == Tstruct) fixup(arg); -#if 0 if (Logger::enabled()) Logger::cout() << "New arg type: " << *arg.ltype << '\n'; -#endif } } }; diff -r 855f188aab7a -r 1e5a14691e77 gen/asmstmt.cpp --- a/gen/asmstmt.cpp Thu Jun 18 15:44:04 2009 +0100 +++ b/gen/asmstmt.cpp Thu Jun 18 15:44:18 2009 +0100 @@ -721,7 +721,7 @@ Logger::cout() << "Arguments:" << '\n'; Logger::indent(); for (std::vector::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(*i) && !llvm::isa(*i)) cout << '\n'; diff -r 855f188aab7a -r 1e5a14691e77 gen/binops.cpp --- a/gen/binops.cpp Thu Jun 18 15:44:04 2009 +0100 +++ b/gen/binops.cpp Thu Jun 18 15:44:18 2009 +0100 @@ -5,6 +5,8 @@ #include "gen/irstate.h" #include "gen/tollvm.h" #include "gen/dvalue.h" +#include "gen/logger.h" +#include "gen/complex.h" ////////////////////////////////////////////////////////////////////////////// @@ -65,3 +67,34 @@ res = gIR->ir->CreateURem(l, r, "tmp"); return new DImValue( targettype, res ); } + +////////////////////////////////////////////////////////////////////////////// + +LLValue* DtoBinNumericEquals(Loc loc, DValue* lhs, DValue* rhs, TOK op) +{ + assert(op == TOKequal || op == TOKnotequal || + op == TOKidentity || op == TOKnotidentity); + Type* t = lhs->getType()->toBasetype(); + assert(t->isfloating()); + Logger::println("numeric equality"); + + LLValue* lv = lhs->getRVal(); + LLValue* rv = rhs->getRVal(); + LLValue* res = 0; + + if (t->iscomplex()) + { + Logger::println("complex"); + res = DtoComplexEquals(loc, op, lhs, rhs); + } + else if (t->isfloating()) + { + Logger::println("floating"); + res = (op == TOKidentity || op == TOKequal) + ? gIR->ir->CreateFCmpOEQ(lv,rv,"tmp") + : gIR->ir->CreateFCmpUNE(lv,rv,"tmp"); + } + + assert(res); + return res; +} diff -r 855f188aab7a -r 1e5a14691e77 gen/classes.cpp --- a/gen/classes.cpp Thu Jun 18 15:44:04 2009 +0100 +++ b/gen/classes.cpp Thu Jun 18 15:44:18 2009 +0100 @@ -491,9 +491,7 @@ { 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); diff -r 855f188aab7a -r 1e5a14691e77 gen/complex.cpp --- a/gen/complex.cpp Thu Jun 18 15:44:04 2009 +0100 +++ b/gen/complex.cpp Thu Jun 18 15:44:18 2009 +0100 @@ -390,7 +390,7 @@ // select predicate llvm::FCmpInst::Predicate cmpop; - if (op == TOKequal) + if (op == TOKequal || op == TOKidentity) cmpop = llvm::FCmpInst::FCMP_OEQ; else cmpop = llvm::FCmpInst::FCMP_UNE; diff -r 855f188aab7a -r 1e5a14691e77 gen/functions.cpp --- a/gen/functions.cpp Thu Jun 18 15:44:04 2009 +0100 +++ b/gen/functions.cpp Thu Jun 18 15:44:18 2009 +0100 @@ -194,9 +194,7 @@ 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; } diff -r 855f188aab7a -r 1e5a14691e77 gen/linker.cpp --- a/gen/linker.cpp Thu Jun 18 15:44:04 2009 +0100 +++ b/gen/linker.cpp Thu Jun 18 15:44:18 2009 +0100 @@ -329,7 +329,7 @@ Logger::println("Linking with: "); std::vector::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 << "'" << " "; diff -r 855f188aab7a -r 1e5a14691e77 gen/llvmhelpers.h --- a/gen/llvmhelpers.h Thu Jun 18 15:44:04 2009 +0100 +++ b/gen/llvmhelpers.h Thu Jun 18 15:44:18 2009 +0100 @@ -119,6 +119,7 @@ DValue* DtoBinMul(Type* resulttype, DValue* lhs, DValue* rhs); DValue* DtoBinDiv(Type* resulttype, DValue* lhs, DValue* rhs); DValue* DtoBinRem(Type* resulttype, DValue* lhs, DValue* rhs); +LLValue* DtoBinNumericEquals(Loc loc, DValue* lhs, DValue* rhs, TOK op); // target stuff void findDefaultTarget(); diff -r 855f188aab7a -r 1e5a14691e77 gen/logger.cpp --- a/gen/logger.cpp Thu Jun 18 15:44:04 2009 +0100 +++ b/gen/logger.cpp Thu Jun 18 15:44:18 2009 +0100 @@ -4,11 +4,34 @@ #include #include #include +#include #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(V) && !llvm::isa(V)) + llvm::WriteAsOperand(OS, &V, true, gIR->module); + else + OS << V; +} namespace Logger { @@ -31,10 +54,10 @@ 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; } diff -r 855f188aab7a -r 1e5a14691e77 gen/logger.h --- a/gen/logger.h Thu Jun 18 15:44:04 2009 +0100 +++ b/gen/logger.h Thu Jun 18 15:44:18 2009 +0100 @@ -1,7 +1,12 @@ #ifndef _llvmd_gen_logger_h_ #define _llvmd_gen_logger_h_ -#include "llvm/Support/Streams.h" +#include + +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 + Stream& operator << (const Ty& Thing) { + if (OS) + Writer::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 friend struct Writer; + // error: function template partial specialization is not allowed + // So I guess type partial specialization + member function will have to do... + template + struct Writer { + static void write(std::ostream& OS, const Ty& Thing) { + OS << Thing; + } + }; + + template + struct Writer { + 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(); diff -r 855f188aab7a -r 1e5a14691e77 gen/toir.cpp --- a/gen/toir.cpp Thu Jun 18 15:44:04 2009 +0100 +++ b/gen/toir.cpp Thu Jun 18 15:44:18 2009 +0100 @@ -1437,6 +1437,8 @@ DValue* l = e1->toElem(p); DValue* r = e2->toElem(p); + LLValue* lv = l->getRVal(); + LLValue* rv = r->getRVal(); Type* t = e1->type->toBasetype(); Type* e2t = e2->type->toBasetype(); @@ -1461,8 +1463,6 @@ default: assert(0); } - LLValue* lv = l->getRVal(); - LLValue* rv = r->getRVal(); if (rv->getType() != lv->getType()) { rv = DtoBitCast(rv, lv->getType()); } @@ -1473,27 +1473,9 @@ } eval = p->ir->CreateICmp(cmpop, lv, rv, "tmp"); } - else if (t->iscomplex()) - { - Logger::println("complex"); - eval = DtoComplexEquals(loc, op, l, r); - } - else if (t->isfloating()) + else if (t->isfloating()) // includes iscomplex { - Logger::println("floating"); - llvm::FCmpInst::Predicate cmpop; - switch(op) - { - case TOKequal: - cmpop = llvm::FCmpInst::FCMP_OEQ; - break; - case TOKnotequal: - cmpop = llvm::FCmpInst::FCMP_UNE; - break; - default: - assert(0); - } - eval = p->ir->CreateFCmp(cmpop, l->getRVal(), r->getRVal(), "tmp"); + eval = DtoBinNumericEquals(loc, l, r, op); } else if (t->ty == Tsarray || t->ty == Tarray) { @@ -2041,55 +2023,53 @@ Logger::print("IdentityExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; - DValue* u = e1->toElem(p); - DValue* v = e2->toElem(p); + DValue* l = e1->toElem(p); + DValue* r = e2->toElem(p); + LLValue* lv = l->getRVal(); + LLValue* rv = r->getRVal(); Type* t1 = e1->type->toBasetype(); // handle dynarray specially if (t1->ty == Tarray) - return new DImValue(type, DtoDynArrayIs(op,u,v)); + return new DImValue(type, DtoDynArrayIs(op,l,r)); // also structs else if (t1->ty == Tstruct) - return new DImValue(type, DtoStructEquals(op,u,v)); + return new DImValue(type, DtoStructEquals(op,l,r)); // FIXME this stuff isn't pretty - LLValue* l = u->getRVal(); - LLValue* r = v->getRVal(); LLValue* eval = 0; if (t1->ty == Tdelegate) { - if (v->isNull()) { - r = NULL; + if (r->isNull()) { + rv = NULL; } else { - assert(l->getType() == r->getType()); + assert(lv->getType() == rv->getType()); } - eval = DtoDelegateEquals(op,l,r); + eval = DtoDelegateEquals(op,lv,rv); } - else if (t1->isfloating()) + else if (t1->isfloating()) // includes iscomplex { - eval = (op == TOKidentity) - ? p->ir->CreateFCmpOEQ(l,r,"tmp") - : p->ir->CreateFCmpONE(l,r,"tmp"); + eval = DtoBinNumericEquals(loc, l, r, op); } else if (t1->ty == Tpointer || t1->ty == Tclass) { - if (l->getType() != r->getType()) { - if (v->isNull()) - r = llvm::ConstantPointerNull::get(isaPointer(l->getType())); + if (lv->getType() != rv->getType()) { + if (r->isNull()) + rv = llvm::ConstantPointerNull::get(isaPointer(lv->getType())); else - r = DtoBitCast(r, l->getType()); + rv = DtoBitCast(rv, lv->getType()); } eval = (op == TOKidentity) - ? p->ir->CreateICmpEQ(l,r,"tmp") - : p->ir->CreateICmpNE(l,r,"tmp"); + ? p->ir->CreateICmpEQ(lv,rv,"tmp") + : p->ir->CreateICmpNE(lv,rv,"tmp"); } else { - assert(l->getType() == r->getType()); + assert(lv->getType() == rv->getType()); eval = (op == TOKidentity) - ? p->ir->CreateICmpEQ(l,r,"tmp") - : p->ir->CreateICmpNE(l,r,"tmp"); + ? p->ir->CreateICmpEQ(lv,rv,"tmp") + : p->ir->CreateICmpNE(lv,rv,"tmp"); } return new DImValue(type, eval); } diff -r 855f188aab7a -r 1e5a14691e77 gen/toobj.cpp --- a/gen/toobj.cpp Thu Jun 18 15:44:04 2009 +0100 +++ b/gen/toobj.cpp Thu Jun 18 15:44:18 2009 +0100 @@ -385,7 +385,7 @@ if (Logger::enabled()) { Logger::println("Assembling with: "); std::vector::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 << "'" << " "; diff -r 855f188aab7a -r 1e5a14691e77 ir/irtypeclass.cpp --- a/ir/irtypeclass.cpp Thu Jun 18 15:44:04 2009 +0100 +++ b/ir/irtypeclass.cpp Thu Jun 18 15:44:18 2009 +0100 @@ -281,9 +281,7 @@ 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(); } diff -r 855f188aab7a -r 1e5a14691e77 ir/irtypestruct.cpp --- a/ir/irtypestruct.cpp Thu Jun 18 15:44:04 2009 +0100 +++ b/ir/irtypestruct.cpp Thu Jun 18 15:44:18 2009 +0100 @@ -227,9 +227,7 @@ // 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(); }