[svn r249] Changed inline asm clobbers to a set instead of a list so we don't get duplicate clobbers.

This commit is contained in:
Tomas Lindquist Olsen
2008-06-08 06:45:54 +02:00
parent fd8cec14e1
commit 68d7827d35
4 changed files with 43 additions and 29 deletions

View File

@@ -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<std::string>::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; i<statements->dim; 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; 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 @@ void AsmBlockStatement::toIR(IRState* p)
{
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 @@ void AsmBlockStatement::toIR(IRState* p)
code += " ; ";
code += a->code;
}
p->ASMs.clear();
asmblock->s.clear();
// append inputs
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 @@ 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");
}

View File

@@ -53,7 +53,7 @@ IRState::IRState()
emitMain = false;
mainFunc = 0;
ir.state = this;
inASM = false;
asmBlock = NULL;
}
IrFunction* IRState::func()

View File

@@ -70,11 +70,16 @@ struct IRAsmStmt
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 @@ struct IRState
FuncDeclVector unitTests;
// for inline asm
std::vector<IRAsmStmt*> ASMs;
bool inASM;
IRAsmBlock* asmBlock;
};
#endif // LLVMDC_GEN_IRSTATE_H

View File

@@ -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;
}