Mercurial > projects > ldc
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; }