From 68d7827d35788e2cabfddbc026f001874f8981e6 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Sun, 8 Jun 2008 06:45:54 +0200 Subject: [PATCH] [svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers. --- gen/asmstmt.cpp | 56 +++++++++++++++++++++++++++------------------- gen/irstate.cpp | 2 +- gen/irstate.h | 10 ++++++--- gen/statements.cpp | 4 ++-- 4 files changed, 43 insertions(+), 29 deletions(-) diff --git a/gen/asmstmt.cpp b/gen/asmstmt.cpp index efcef5cf..ce50fc93 100644 --- a/gen/asmstmt.cpp +++ b/gen/asmstmt.cpp @@ -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 @@ AsmStatement::toIR(IRState * irs) 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 @@ assert(0); // 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 @@ assert(0); 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 @@ assert(0); 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 @@ void AsmBlockStatement::toIR(IRState* p) 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 @@ void AsmBlockStatement::toIR(IRState* p) 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 += 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 @@ void AsmBlockStatement::toIR(IRState* p) 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 --git a/gen/irstate.cpp b/gen/irstate.cpp index 66e8aaaf..0a9063ef 100644 --- a/gen/irstate.cpp +++ b/gen/irstate.cpp @@ -53,7 +53,7 @@ IRState::IRState() emitMain = false; mainFunc = 0; ir.state = this; - inASM = false; + asmBlock = NULL; } IrFunction* IRState::func() diff --git a/gen/irstate.h b/gen/irstate.h index 98392fb8..1aad0c78 100644 --- a/gen/irstate.h +++ b/gen/irstate.h @@ -70,11 +70,16 @@ struct IRAsmStmt 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 @@ struct IRState FuncDeclVector unitTests; // for inline asm - std::vector ASMs; - bool inASM; + IRAsmBlock* asmBlock; }; #endif // LLVMDC_GEN_IRSTATE_H diff --git a/gen/statements.cpp b/gen/statements.cpp index d2b3d210..117011e6 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -993,13 +993,13 @@ void LabelStatement::toIR(IRState* p) 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; }