changeset 1505:1e5a14691e77

Automated merge with http://hg.dsource.org/projects/ldc
author Robert Clipsham <robert@octarineparrot.com>
date Thu, 18 Jun 2009 15:44:18 +0100
parents cc5fee7836dc (diff) 855f188aab7a (current diff)
children 76936858d1c6
files gen/llvmhelpers.h
diffstat 15 files changed, 153 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- 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
         }
     }
 }
--- 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
         }
     }
 };
--- 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<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';
--- 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;
+}
--- 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);
--- 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;
--- 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;
 }
--- 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 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 << "'" << " ";
--- 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();
--- 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 <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 @@
             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;
     }
--- 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 <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();
--- 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);
 }
--- 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 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 << "'" << " ";
--- 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();
 }
--- 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();
 }