Allow InstAlias's to use immediate matcher patterns that xform the value.

For example,

On ARM, "mov r3, #-3" is an alias for "mvn r3, #2", so we want to use a
matcher pattern that handles the bitwise negation when mapping to t2MVNi.

llvm-svn: 143233
This commit is contained in:
Jim Grosbach 2011-10-28 22:32:53 +00:00
parent 5524ce7d82
commit d1f1b79b52
2 changed files with 29 additions and 5 deletions

View File

@ -591,7 +591,8 @@ private:
/// getOperandClass - Lookup or create the class for the given operand.
ClassInfo *getOperandClass(const CGIOperandList::OperandInfo &OI,
int SubOpIdx = -1);
int SubOpIdx);
ClassInfo *getOperandClass(Record *Rec, int SubOpIdx);
/// BuildRegisterClasses - Build the ClassInfo* instances for register
/// classes.
@ -870,7 +871,11 @@ AsmMatcherInfo::getOperandClass(const CGIOperandList::OperandInfo &OI,
Record *Rec = OI.Rec;
if (SubOpIdx != -1)
Rec = dynamic_cast<DefInit*>(OI.MIOperandInfo->getArg(SubOpIdx))->getDef();
return getOperandClass(Rec, SubOpIdx);
}
ClassInfo *
AsmMatcherInfo::getOperandClass(Record *Rec, int SubOpIdx) {
if (Rec->isSubClassOf("RegisterOperand")) {
// RegisterOperand may have an associated ParserMatchClass. If it does,
// use it, else just fall back to the underlying register class.
@ -1375,9 +1380,11 @@ void AsmMatcherInfo::BuildAliasOperandReference(MatchableInfo *II,
CGA.ResultOperands[i].getName() == OperandName) {
// It's safe to go with the first one we find, because CodeGenInstAlias
// validates that all operands with the same name have the same record.
unsigned ResultIdx = CGA.ResultInstOperandIndex[i].first;
Op.SubOpIdx = CGA.ResultInstOperandIndex[i].second;
Op.Class = getOperandClass(CGA.ResultInst->Operands[ResultIdx],
// Use the match class from the Alias definition, not the
// destination instruction, as we may have an immediate that's
// being munged by the match class.
Op.Class = getOperandClass(CGA.ResultOperands[i].getRecord(),
Op.SubOpIdx);
Op.SrcOpName = OperandName;
return;

View File

@ -428,8 +428,11 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
if (ADI && ADI->getDef()->isSubClassOf("RegisterClass")) {
if (!InstOpRec->isSubClassOf("RegisterClass"))
return false;
return T.getRegisterClass(InstOpRec)
.hasSubClass(&T.getRegisterClass(ADI->getDef()));
if (!T.getRegisterClass(InstOpRec)
.hasSubClass(&T.getRegisterClass(ADI->getDef())))
return false;
ResOp = ResultOperand(Result->getArgName(AliasOpNo), ADI->getDef());
return true;
}
// Handle explicit registers.
@ -473,6 +476,7 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
return true;
}
// Literal integers.
if (IntInit *II = dynamic_cast<IntInit*>(Arg)) {
if (hasSubOps || !InstOpRec->isSubClassOf("Operand"))
return false;
@ -484,6 +488,19 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
return true;
}
// If both are Operands with the same MVT, allow the conversion. It's
// up to the user to make sure the values are appropriate, just like
// for isel Pat's.
if (InstOpRec->isSubClassOf("Operand") &&
ADI->getDef()->isSubClassOf("Operand")) {
// FIXME: What other attributes should we check here? Identical
// MIOperandInfo perhaps?
if (InstOpRec->getValueInit("Type") != ADI->getDef()->getValueInit("Type"))
return false;
ResOp = ResultOperand(Result->getArgName(AliasOpNo), ADI->getDef());
return true;
}
return false;
}