# HG changeset patch # User lindquist # Date 1212900354 -7200 # Node ID 76ee1bbe487e7bbad8e320e95cc1238436caf17e # Parent 092468448d2577d2233d1f25b22d6e3063bebbbc [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers. diff -r 092468448d25 -r 76ee1bbe487e gen/asmstmt.cpp --- 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::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; idim; 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; iASMs[i]; + IRAsmStmt* a = asmblock->s[i]; assert(a); size_t onn = a->out.size(); for (size_t j=0; jout_c; } - if (!a->clobbers.empty()) - { - clobbers += a->clobbers; - } remap_outargs(a->code, onn, asmIdx); } for (size_t i=0; iASMs[i]; + IRAsmStmt* a = asmblock->s[i]; assert(a); size_t inn = a->in.size(); for (size_t j=0; jcode; } - p->ASMs.clear(); + asmblock->s.clear(); + + // append inputs + out_c += in_c; - out_c += in_c; - out_c += clobbers; + // append clobbers + typedef std::set::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"); } diff -r 092468448d25 -r 76ee1bbe487e gen/irstate.cpp --- 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() diff -r 092468448d25 -r 76ee1bbe487e gen/irstate.h --- 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 out; std::vector in; }; +struct IRAsmBlock +{ + std::vector s; + std::set clobs; +}; + // represents the module struct IRState { @@ -152,8 +157,7 @@ FuncDeclVector unitTests; // for inline asm - std::vector ASMs; - bool inASM; + IRAsmBlock* asmBlock; }; #endif // LLVMDC_GEN_IRSTATE_H diff -r 092468448d25 -r 76ee1bbe487e gen/statements.cpp --- 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; }