changeset 233:76ee1bbe487e trunk

[svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.
author lindquist
date Sun, 08 Jun 2008 06:45:54 +0200
parents 092468448d25
children 9760f54af0b7
files gen/asmstmt.cpp gen/irstate.cpp gen/irstate.h gen/statements.cpp
diffstat 4 files changed, 44 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/gen/asmstmt.cpp	Sun Jun 08 06:15:51 2008 +0200
+++ b/gen/asmstmt.cpp	Sun Jun 08 06:45:54 2008 +0200
@@ -25,6 +25,7 @@
 #include "gen/dvalue.h"
 #include "gen/tollvm.h"
 #include "gen/logger.h"
+#include "gen/todebug.h"
 
 typedef enum {
     Arg_Integer,
@@ -217,11 +218,16 @@
     Logger::println("AsmStatement::toIR(): %s", loc.toChars());
     LOG_SCOPE;
 
-// FIXME
-//    gen.doLineNote( loc );
+    // get asm block
+    IRAsmBlock* asmblock = irs->asmBlock;
+    assert(asmblock);
+
+    // debug info
+    if (global.params.symdebug)
+        DtoDwarfStopPoint(loc.linnum);
 
     if (! asmcode)
-	return;
+    return;
 
     static std::string i_cns = "i";
     static std::string p_cns = "i";
@@ -408,7 +414,6 @@
     // rewrite GCC-style constraints to LLVM-style constraints
     std::string llvmOutConstraints;
     std::string llvmInConstraints;
-    std::string llvmClobbers;
     int n = 0;
     typedef std::deque<std::string>::iterator it;
     for(it i = output_constraints.begin(), e = output_constraints.end(); i != e; ++i, ++n) {
@@ -431,8 +436,10 @@
         llvmInConstraints += ",";
     }
 
+    std::string clobstr;
     for(it i = clobbers.begin(), e = clobbers.end(); i != e; ++i) {
-        llvmClobbers += "~{" + *i + "},";
+        clobstr = "~{" + *i + "},";
+        asmblock->clobs.insert(clobstr);
     }
 
     // excessive commas are removed later...
@@ -442,10 +449,9 @@
     asmStmt->code = insnt;
     asmStmt->out_c = llvmOutConstraints;
     asmStmt->in_c = llvmInConstraints;
-    asmStmt->clobbers = llvmClobbers;
     asmStmt->out.insert(asmStmt->out.begin(), output_values.begin(), output_values.end());
     asmStmt->in.insert(asmStmt->in.begin(), input_values.begin(), input_values.end());
-    irs->ASMs.push_back(asmStmt);
+    asmblock->s.push_back(asmStmt);
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -505,12 +511,10 @@
     LOG_SCOPE;
     Logger::println("BEGIN ASM");
 
-    assert(!p->inASM);
-    p->inASM = true;
-
-    // rest idx
-    size_t asmIdx = 0;
-    assert(p->ASMs.empty());
+    // create asm block structure
+    assert(!p->asmBlock);
+    IRAsmBlock* asmblock = new IRAsmBlock;
+    p->asmBlock = asmblock;
 
     // do asm statements
     for (int i=0; i<statements->dim; i++)
@@ -530,11 +534,12 @@
     std::string in_c;
     std::string clobbers;
     std::string code;
+    size_t asmIdx = 0;
 
-    size_t n = p->ASMs.size();
+    size_t n = asmblock->s.size();
     for (size_t i=0; i<n; ++i)
     {
-        IRAsmStmt* a = p->ASMs[i];
+        IRAsmStmt* a = asmblock->s[i];
         assert(a);
         size_t onn = a->out.size();
         for (size_t j=0; j<onn; ++j)
@@ -546,15 +551,11 @@
         {
             out_c += a->out_c;
         }
-        if (!a->clobbers.empty())
-        {
-            clobbers += a->clobbers;
-        }
         remap_outargs(a->code, onn, asmIdx);
     }
     for (size_t i=0; i<n; ++i)
     {
-        IRAsmStmt* a = p->ASMs[i];
+        IRAsmStmt* a = asmblock->s[i];
         assert(a);
         size_t inn = a->in.size();
         for (size_t j=0; j<inn; ++j)
@@ -571,10 +572,19 @@
             code += " ; ";
         code += a->code;
     }
-    p->ASMs.clear();
+    asmblock->s.clear();
+
+    // append inputs
+    out_c += in_c;
 
-    out_c += in_c;
-    out_c += clobbers;
+    // append clobbers
+    typedef std::set<std::string>::iterator clobs_it;
+    for (clobs_it i=asmblock->clobs.begin(); i!=asmblock->clobs.end(); ++i)
+    {
+        out_c += *i;
+    }
+
+    // remove excessive comma
     if (!out_c.empty())
         out_c.resize(out_c.size()-1);
 
@@ -593,7 +603,7 @@
     args.insert(args.end(), inargs.begin(), inargs.end());
     llvm::CallInst* call = p->ir->CreateCall(ia, args.begin(), args.end(), "");
 
-    p->inASM = false;
+    p->asmBlock = NULL;
     Logger::println("END ASM");
 }
 
--- a/gen/irstate.cpp	Sun Jun 08 06:15:51 2008 +0200
+++ b/gen/irstate.cpp	Sun Jun 08 06:45:54 2008 +0200
@@ -53,7 +53,7 @@
     emitMain = false;
     mainFunc = 0;
     ir.state = this;
-    inASM = false;
+    asmBlock = NULL;
 }
 
 IrFunction* IRState::func()
--- a/gen/irstate.h	Sun Jun 08 06:15:51 2008 +0200
+++ b/gen/irstate.h	Sun Jun 08 06:45:54 2008 +0200
@@ -70,11 +70,16 @@
     std::string code;
     std::string out_c;
     std::string in_c;
-    std::string clobbers;
     std::vector<LLValue*> out;
     std::vector<LLValue*> in;
 };
 
+struct IRAsmBlock
+{
+    std::vector<IRAsmStmt*> s;
+    std::set<std::string> clobs;
+};
+
 // represents the module
 struct IRState
 {
@@ -152,8 +157,7 @@
     FuncDeclVector unitTests;
 
     // for inline asm
-    std::vector<IRAsmStmt*> ASMs;
-    bool inASM;
+    IRAsmBlock* asmBlock;
 };
 
 #endif // LLVMDC_GEN_IRSTATE_H
--- a/gen/statements.cpp	Sun Jun 08 06:15:51 2008 +0200
+++ b/gen/statements.cpp	Sun Jun 08 06:45:54 2008 +0200
@@ -993,13 +993,13 @@
     LOG_SCOPE;
 
     // if it's an inline asm label, we don't create a basicblock, just emit it in the asm
-    if (p->inASM)
+    if (p->asmBlock)
     {
         IRAsmStmt* a = new IRAsmStmt;
         a->code = ".LDASM";
         a->code += ident->toChars();
         a->code += ":";
-        p->ASMs.push_back(a);
+        p->asmBlock->s.push_back(a);
         return;
     }