std::map<std::string, std::string> VariableMap;
// Node to operator mapping
std::map<std::string, Record*> OperatorMap;
+ // Name of the folded node which produces a flag.
+ std::pair<std::string, unsigned> FoldedFlag;
// Names of all the folded nodes which produce chains.
std::vector<std::pair<std::string, unsigned> > FoldedChains;
// Original input chain(s).
std::vector<std::pair<std::string, std::string> > OrigChains;
std::set<std::string> Duplicates;
+ /// LSI - Load/Store information.
+ /// Save loads/stores matched by a pattern, and generate a MemOperandSDNode
+ /// for each memory access. This facilitates the use of AliasAnalysis in
+ /// the backend.
+ std::vector<std::string> LSI;
+
/// GeneratedCode - This is the buffer that we emit code to. The first int
/// indicates whether this is an exit predicate (something that should be
/// tested, and if true, the match fails) [when 1], or normal code to emit
void EmitMatchCode(TreePatternNode *N, TreePatternNode *P,
const std::string &RootName, const std::string &ChainSuffix,
bool &FoundChain) {
+
+ // Save loads/stores matched by a pattern.
+ if (!N->isLeaf() && N->getName().empty()) {
+ std::string EnumName = N->getOperator()->getValueAsString("Opcode");
+ if (EnumName == "ISD::LOAD" ||
+ EnumName == "ISD::STORE") {
+ LSI.push_back(RootName);
+ }
+ }
+
bool isRoot = (P == NULL);
// Emit instruction predicates. Each predicate is just a string for now.
if (isRoot) {
emitCheck(RootName + ".getOpcode() == " +
CInfo.getEnumName());
EmitMatchCode(Child, Parent, RootName, ChainSuffix, FoundChain);
- if (NodeHasProperty(Child, SDNPHasChain, CGP))
+ bool HasChain = false;
+ if (NodeHasProperty(Child, SDNPHasChain, CGP)) {
+ HasChain = true;
FoldedChains.push_back(std::make_pair(RootName, CInfo.getNumResults()));
+ }
+ if (NodeHasProperty(Child, SDNPOutFlag, CGP)) {
+ assert(FoldedFlag.first == "" && FoldedFlag.second == 0 &&
+ "Pattern folded multiple nodes which produce flags?");
+ FoldedFlag = std::make_pair(RootName,
+ CInfo.getNumResults() + (unsigned)HasChain);
+ }
} else {
// If this child has a name associated with it, capture it in VarMap. If
// we already saw this in the pattern, emit code to verify dagness.
Val = TmpVar;
ModifiedVal = true;
NodeOps.push_back(Val);
+ } else if (!N->isLeaf() && N->getOperator()->getName() == "fpimm") {
+ assert(N->getExtTypes().size() == 1 && "Multiple types not handled!");
+ std::string TmpVar = "Tmp" + utostr(ResNo);
+ emitCode("SDOperand " + TmpVar +
+ " = CurDAG->getTargetConstantFP(cast<ConstantFPSDNode>(" +
+ Val + ")->getValueAPF(), cast<ConstantFPSDNode>(" + Val +
+ ")->getValueType(0));");
+ // Add Tmp<ResNo> to VariableMap, so that we don't multiply select this
+ // value if used multiple times by this pattern result.
+ Val = TmpVar;
+ ModifiedVal = true;
+ NodeOps.push_back(Val);
} else if (!N->isLeaf() && N->getOperator()->getName() == "texternalsym"){
Record *Op = OperatorMap[N->getName()];
// Transform ExternalSymbol to TargetExternalSymbol
}
}
+ // Generate MemOperandSDNodes nodes for each memory accesses covered by this
+ // pattern.
+ if (isRoot) {
+ std::vector<std::string>::const_iterator mi, mie;
+ for (mi = LSI.begin(), mie = LSI.end(); mi != mie; ++mi) {
+ emitCode("SDOperand LSI_" + *mi + " = "
+ "CurDAG->getMemOperand(cast<LSBaseSDNode>(" +
+ *mi + ")->getMemOperand());");
+ AllOps.push_back("LSI_" + *mi);
+ }
+ }
+
// Emit all the chain and CopyToReg stuff.
bool ChainEmitted = NodeHasChain;
if (NodeHasChain)
}
if (NodeHasOutFlag) {
- emitCode("ReplaceUses(SDOperand(N.Val, " +
- utostr(NumPatResults + (unsigned)InputHasChain)
- +"), InFlag);");
+ if (FoldedFlag.first != "") {
+ emitCode("ReplaceUses(SDOperand(" + FoldedFlag.first + ".Val, " +
+ utostr(FoldedFlag.second) + "), InFlag);");
+ } else {
+ assert(NodeHasProperty(Pattern, SDNPOutFlag, CGP));
+ emitCode("ReplaceUses(SDOperand(N.Val, " +
+ utostr(NumPatResults + (unsigned)InputHasChain)
+ +"), InFlag);");
+ }
NeedReplace = true;
}
<< "}\n\n";
OS << "SDNode *Select_DECLARE(const SDOperand &N) {\n"
- << " MachineModuleInfo *MMI = CurDAG->getMachineModuleInfo();\n"
<< " SDOperand Chain = N.getOperand(0);\n"
<< " SDOperand N1 = N.getOperand(1);\n"
<< " SDOperand N2 = N.getOperand(2);\n"
<< " }\n"
<< " int FI = cast<FrameIndexSDNode>(N1)->getIndex();\n"
<< " GlobalValue *GV = cast<GlobalAddressSDNode>(N2)->getGlobal();\n"
- << " // FIXME. Handle variable declarations later since it lives on.\n"
- << " MMI->RecordVariable(GV, FI);\n"
<< " SDOperand Tmp1 = "
<< "CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());\n"
<< " SDOperand Tmp2 = "
<< " case ISD::Register:\n"
<< " case ISD::HANDLENODE:\n"
<< " case ISD::TargetConstant:\n"
+ << " case ISD::TargetConstantFP:\n"
<< " case ISD::TargetConstantPool:\n"
<< " case ISD::TargetFrameIndex:\n"
<< " case ISD::TargetExternalSymbol:\n"