Fixed bug in manual variable spill() and added a test-case for that.

Minor changes in annotations.
This commit is contained in:
kobalicekp
2014-03-22 21:28:56 +01:00
parent 995730b929
commit 2bf1af0dde
2 changed files with 76 additions and 19 deletions

View File

@@ -396,6 +396,58 @@ struct X86Test_AllocManual : public X86Test {
} }
}; };
// ============================================================================
// [X86Test_AllocUseMem]
// ============================================================================
struct X86Test_AllocUseMem : public X86Test {
X86Test_AllocUseMem() : X86Test("[Alloc] Alloc/use mem") {}
static void add(PodVector<X86Test*>& tests) {
tests.append(new X86Test_AllocUseMem());
}
virtual void compile(Compiler& c) {
c.addFunc(kFuncConvHost, FuncBuilder2<int, int, int>());
GpVar iIdx(c, kVarTypeInt32);
GpVar iEnd(c, kVarTypeInt32);
GpVar aIdx(c, kVarTypeInt32);
GpVar aEnd(c, kVarTypeInt32);
Label L_1(c);
c.setArg(0, aIdx);
c.setArg(1, aEnd);
c.mov(iIdx, aIdx);
c.mov(iEnd, aEnd);
c.spill(iEnd);
c.bind(L_1);
c.inc(iIdx);
c.cmp(iIdx, iEnd.m());
c.jne(L_1);
c.ret(iIdx);
c.endFunc();
}
virtual bool run(void* _func, StringBuilder& result, StringBuilder& expect) {
typedef int (*Func)(int, int);
Func func = asmjit_cast<Func>(_func);
int resultRet = func(10, 20);
int expectRet = 20;
result.setFormat("ret=%d", resultRet);
expect.setFormat("ret=%d", expectRet);
return resultRet == expectRet;
}
};
// ============================================================================ // ============================================================================
// [X86Test_AllocMany1] // [X86Test_AllocMany1]
// ============================================================================ // ============================================================================
@@ -2284,6 +2336,7 @@ X86TestSuite::X86TestSuite() :
// Alloc. // Alloc.
ADD_TEST(X86Test_AllocBase); ADD_TEST(X86Test_AllocBase);
ADD_TEST(X86Test_AllocManual); ADD_TEST(X86Test_AllocManual);
ADD_TEST(X86Test_AllocUseMem);
ADD_TEST(X86Test_AllocMany1); ADD_TEST(X86Test_AllocMany1);
ADD_TEST(X86Test_AllocMany2); ADD_TEST(X86Test_AllocMany2);
ADD_TEST(X86Test_AllocImul1); ADD_TEST(X86Test_AllocImul1);

View File

@@ -2777,11 +2777,11 @@ static void X86X64Context_annotateVariable(X86X64Context* self,
const char* name = vd->getName(); const char* name = vd->getName();
if (name != NULL && name[0] != '\0') { if (name != NULL && name[0] != '\0') {
sb._appendString(name); sb.appendString(name);
} }
else { else {
sb._appendChar('v'); sb.appendChar('v');
sb._appendUInt32(vd->getId() & kOperandIdNum); sb.appendUInt(vd->getId() & kOperandIdNum);
} }
} }
@@ -2795,7 +2795,7 @@ static void X86X64Context_annotateOperand(X86X64Context* self,
const Mem* m = static_cast<const Mem*>(op); const Mem* m = static_cast<const Mem*>(op);
bool isAbsolute = false; bool isAbsolute = false;
sb._appendChar('['); sb.appendChar('[');
switch (m->getMemType()) { switch (m->getMemType()) {
case kMemTypeBaseIndex: case kMemTypeBaseIndex:
case kMemTypeStackIndex: case kMemTypeStackIndex:
@@ -2816,12 +2816,12 @@ static void X86X64Context_annotateOperand(X86X64Context* self,
} }
if (m->hasIndex()) { if (m->hasIndex()) {
sb._appendChar('+'); sb.appendChar('+');
X86X64Context_annotateVariable(self, sb, self->_compiler->getVdById(m->getIndex())); X86X64Context_annotateVariable(self, sb, self->_compiler->getVdById(m->getIndex()));
if (m->getShift()) { if (m->getShift()) {
sb._appendChar('*'); sb.appendChar('*');
sb._appendChar("1248"[m->getShift() & 3]); sb.appendChar("1248"[m->getShift() & 3]);
} }
} }
@@ -2835,17 +2835,17 @@ static void X86X64Context_annotateOperand(X86X64Context* self,
prefix = '-'; prefix = '-';
} }
sb._appendChar(prefix); sb.appendChar(prefix);
/* /*
if ((loggerOptions & (1 << kLoggerOptionHexDisplacement)) != 0 && dispOffset > 9) { if ((loggerOptions & (1 << kLoggerOptionHexDisplacement)) != 0 && dispOffset > 9) {
sb._appendString("0x", 2); sb.appendString("0x", 2);
base = 16; base = 16;
} }
*/ */
sb.appendUInt(static_cast<uint32_t>(dispOffset), base); sb.appendUInt(static_cast<uint32_t>(dispOffset), base);
} }
sb._appendChar(']'); sb.appendChar(']');
} }
else if (op->isImm()) { else if (op->isImm()) {
const Imm* i = static_cast<const Imm*>(op); const Imm* i = static_cast<const Imm*>(op);
@@ -2861,22 +2861,19 @@ static void X86X64Context_annotateOperand(X86X64Context* self,
sb.appendFormat("L%u", op->getId()); sb.appendFormat("L%u", op->getId());
} }
else { else {
sb._appendString("None", 4); sb.appendString("None", 4);
} }
} }
static bool X86X64Context_annotateInstruction(X86X64Context* self, static bool X86X64Context_annotateInstruction(X86X64Context* self,
StringBuilder& sb, uint32_t code, const Operand* opList, uint32_t opCount) { StringBuilder& sb, uint32_t code, const Operand* opList, uint32_t opCount) {
if (!sb.reserve(sb.getLength() + 128)) sb.appendString(_instInfo[code].getName());
return false;
sb._appendString(_instInfo[code].getName());
for (uint32_t i = 0; i < opCount; i++) { for (uint32_t i = 0; i < opCount; i++) {
if (i == 0) if (i == 0)
sb._appendChar(' '); sb.appendChar(' ');
else else
sb._appendString(", ", 2); sb.appendString(", ", 2);
X86X64Context_annotateOperand(self, sb, &opList[i]); X86X64Context_annotateOperand(self, sb, &opList[i]);
} }
return true; return true;
@@ -2888,8 +2885,9 @@ Error X86X64Context::annotate() {
BaseNode* node_ = func; BaseNode* node_ = func;
BaseNode* end = func->getEnd(); BaseNode* end = func->getEnd();
StringBuilderT<128> sb;
Zone& sa = _compiler->_stringAllocator; Zone& sa = _compiler->_stringAllocator;
StringBuilderT<128> sb;
uint32_t maxLen = 0; uint32_t maxLen = 0;
while (node_ != end) { while (node_ != end) {
@@ -3475,6 +3473,12 @@ ASMJIT_INLINE void X86X64VarAlloc::plan() {
occupied |= regMask; occupied |= regMask;
continue; continue;
} }
else if ((vaFlags & kVarAttrInOutMem) != 0) {
uint32_t regIndex = vd->getRegIndex();
if (regIndex != kInvalidReg && (vaFlags & kVarAttrInOutMem) != kVarAttrOutMem) {
willSpill |= IntUtil::mask(regIndex);
}
}
} }
// Set calculated masks back to the allocator; needed by spill() and alloc(). // Set calculated masks back to the allocator; needed by spill() and alloc().
@@ -3505,7 +3509,7 @@ ASMJIT_INLINE void X86X64VarAlloc::spill() {
VarData* vd = sVars[i]; VarData* vd = sVars[i];
ASMJIT_ASSERT(vd != NULL); ASMJIT_ASSERT(vd != NULL);
ASMJIT_ASSERT(vd->getVa() == NULL); ASMJIT_ASSERT(vd->getVa() == NULL || (vd->getVa()->getFlags() & kVarAttrInOutReg) == 0);
if (vd->isModified() && availableRegs) { if (vd->isModified() && availableRegs) {
uint32_t m = guessSpill<C>(vd, availableRegs); uint32_t m = guessSpill<C>(vd, availableRegs);