bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
                                           unsigned Opc) {
  ListInit *Predicates = AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates");
  for (unsigned i = 0; i < Predicates->getSize(); ++i) {
    Record *Pred = Predicates->getElementAsRecord(i);
    if (!Pred->getValue("AssemblerMatcherPredicate"))
      continue;

    std::string P = Pred->getValueAsString("AssemblerCondString");

    if (!P.length())
      continue;

    if (i != 0)
      o << " && ";

    StringRef SR(P);
    std::pair<StringRef, StringRef> pairs = SR.split(',');
    while (pairs.second.size()) {
      emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace);
      o << " && ";
      pairs = pairs.second.split(',');
    }
    emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace);
  }
  return Predicates->getSize() > 0;
}
Ejemplo n.º 2
0
CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
  // Rename anonymous register classes.
  if (R->getName().size() > 9 && R->getName()[9] == '.') {
    static unsigned AnonCounter = 0;
    R->setName("AnonRegClass_"+utostr(AnonCounter++));
  }

  std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes");
  for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
    Record *Type = TypeList[i];
    if (!Type->isSubClassOf("ValueType"))
      throw "RegTypes list member '" + Type->getName() +
        "' does not derive from the ValueType class!";
    VTs.push_back(getValueType(Type));
  }
  assert(!VTs.empty() && "RegisterClass must contain at least one ValueType!");

  std::vector<Record*> RegList = R->getValueAsListOfDefs("MemberList");
  for (unsigned i = 0, e = RegList.size(); i != e; ++i) {
    Record *Reg = RegList[i];
    if (!Reg->isSubClassOf("Register"))
      throw "Register Class member '" + Reg->getName() +
            "' does not derive from the Register class!";
    Elements.push_back(Reg);
  }

  // SubRegClasses is a list<dag> containing (RC, subregindex, ...) dags.
  ListInit *SRC = R->getValueAsListInit("SubRegClasses");
  for (ListInit::const_iterator i = SRC->begin(), e = SRC->end(); i != e; ++i) {
    DagInit *DAG = dynamic_cast<DagInit*>(*i);
    if (!DAG) throw "SubRegClasses must contain DAGs";
    DefInit *DAGOp = dynamic_cast<DefInit*>(DAG->getOperator());
    Record *RCRec;
    if (!DAGOp || !(RCRec = DAGOp->getDef())->isSubClassOf("RegisterClass"))
      throw "Operator '" + DAG->getOperator()->getAsString() +
        "' in SubRegClasses is not a RegisterClass";
    // Iterate over args, all SubRegIndex instances.
    for (DagInit::const_arg_iterator ai = DAG->arg_begin(), ae = DAG->arg_end();
         ai != ae; ++ai) {
      DefInit *Idx = dynamic_cast<DefInit*>(*ai);
      Record *IdxRec;
      if (!Idx || !(IdxRec = Idx->getDef())->isSubClassOf("SubRegIndex"))
        throw "Argument '" + (*ai)->getAsString() +
          "' in SubRegClasses is not a SubRegIndex";
      if (!SubRegClasses.insert(std::make_pair(IdxRec, RCRec)).second)
        throw "SubRegIndex '" + IdxRec->getName() + "' mentioned twice";
    }
  }

  // Allow targets to override the size in bits of the RegisterClass.
  unsigned Size = R->getValueAsInt("Size");

  Namespace = R->getValueAsString("Namespace");
  SpillSize = Size ? Size : EVT(VTs[0]).getSizeInBits();
  SpillAlignment = R->getValueAsInt("Alignment");
  CopyCost = R->getValueAsInt("CopyCost");
  MethodBodies = R->getValueAsCode("MethodBodies");
  MethodProtos = R->getValueAsCode("MethodProtos");
}
Ejemplo n.º 3
0
static void emitEnums(raw_ostream &OS, RecordKeeper &Records) {

  std::vector<Record*> InstrMapVec;
  InstrMapVec = Records.getAllDerivedDefinitions("InstrMapping");
  std::map<std::string, std::vector<Init*> > ColFieldValueMap;

  // Iterate over all InstrMapping records and create a map between column
  // fields and their possible values across all records.
  for (unsigned i = 0, e = InstrMapVec.size(); i < e; i++) {
    Record *CurMap = InstrMapVec[i];
    ListInit *ColFields;
    ColFields = CurMap->getValueAsListInit("ColFields");
    ListInit *List = CurMap->getValueAsListInit("ValueCols");
    std::vector<ListInit*> ValueCols;
    unsigned ListSize = List->size();

    for (unsigned j = 0; j < ListSize; j++) {
      ListInit *ListJ = dyn_cast<ListInit>(List->getElement(j));

      if (ListJ->size() != ColFields->size())
        PrintFatalError("Record `" + CurMap->getName() + "', field "
          "`ValueCols' entries don't match with the entries in 'ColFields' !");
      ValueCols.push_back(ListJ);
    }

    for (unsigned j = 0, endCF = ColFields->size(); j < endCF; j++) {
      for (unsigned k = 0; k < ListSize; k++){
        std::string ColName = ColFields->getElement(j)->getAsUnquotedString();
        ColFieldValueMap[ColName].push_back((ValueCols[k])->getElement(j));
      }
    }
  }

  for (std::map<std::string, std::vector<Init*> >::iterator
       II = ColFieldValueMap.begin(), IE = ColFieldValueMap.end();
       II != IE; II++) {
    std::vector<Init*> FieldValues = (*II).second;

    // Delete duplicate entries from ColFieldValueMap
    for (unsigned i = 0; i < FieldValues.size() - 1; i++) {
      Init *CurVal = FieldValues[i];
      for (unsigned j = i+1; j < FieldValues.size(); j++) {
        if (CurVal == FieldValues[j]) {
          FieldValues.erase(FieldValues.begin()+j);
        }
      }
    }

    // Emit enumerated values for the column fields.
    OS << "enum " << (*II).first << " {\n";
    for (unsigned i = 0, endFV = FieldValues.size(); i < endFV; i++) {
      OS << "\t" << (*II).first << "_" << FieldValues[i]->getAsUnquotedString();
      if (i != endFV - 1)
        OS << ",\n";
      else
        OS << "\n};\n\n";
    }
  }
}
Ejemplo n.º 4
0
Record *MapTableEmitter::getInstrForColumn(Record *KeyInstr,
                                           ListInit *CurValueCol) {
  ListInit *RowFields = InstrMapDesc.getRowFields();
  std::vector<Init*> KeyValue;

  // Construct KeyValue using KeyInstr's values for RowFields.
  for (Init *RowField : RowFields->getValues()) {
    Init *KeyInstrVal = KeyInstr->getValue(RowField)->getValue();
    KeyValue.push_back(KeyInstrVal);
  }

  // Get all the instructions that share the same KeyValue as the KeyInstr
  // in RowInstrMap. We search through these instructions to find a match
  // for the current column, i.e., the instruction which has the same values
  // as CurValueCol for all the fields in ColFields.
  const std::vector<Record*> &RelatedInstrVec = RowInstrMap[KeyValue];

  ListInit *ColFields = InstrMapDesc.getColFields();
  Record *MatchInstr = nullptr;

  for (unsigned i = 0, e = RelatedInstrVec.size(); i < e; i++) {
    bool MatchFound = true;
    Record *CurInstr = RelatedInstrVec[i];
    for (unsigned j = 0, endCF = ColFields->size();
        (j < endCF) && MatchFound; j++) {
      Init *ColFieldJ = ColFields->getElement(j);
      Init *CurInstrInit = CurInstr->getValue(ColFieldJ)->getValue();
      std::string CurInstrVal = CurInstrInit->getAsUnquotedString();
      Init *ColFieldJVallue = CurValueCol->getElement(j);
      MatchFound = (CurInstrVal == ColFieldJVallue->getAsUnquotedString());
    }

    if (MatchFound) {
      if (MatchInstr) {
        // Already had a match
        // Error if multiple matches are found for a column.
        std::string KeyValueStr;
        for (Init *Value : KeyValue) {
          if (!KeyValueStr.empty())
            KeyValueStr += ", ";
          KeyValueStr += Value->getAsString();
        }

        PrintFatalError("Multiple matches found for `" + KeyInstr->getName() +
              "', for the relation `" + InstrMapDesc.getName() + "', row fields [" +
              KeyValueStr + "], column `" + CurValueCol->getAsString() + "'");
      }
      MatchInstr = CurInstr;
    }
  }
  return MatchInstr;
}
Ejemplo n.º 5
0
bool MapTableEmitter::isKeyColInstr(Record* CurInstr) {
  ListInit *ColFields = InstrMapDesc.getColFields();
  ListInit *KeyCol = InstrMapDesc.getKeyCol();

  // Check if the instruction is a KeyCol instruction.
  bool MatchFound = true;
  for (unsigned j = 0, endCF = ColFields->size();
      (j < endCF) && MatchFound; j++) {
    RecordVal *ColFieldName = CurInstr->getValue(ColFields->getElement(j));
    std::string CurInstrVal = ColFieldName->getValue()->getAsUnquotedString();
    std::string KeyColValue = KeyCol->getElement(j)->getAsUnquotedString();
    MatchFound = (CurInstrVal == KeyColValue);
  }
  return MatchFound;
}
Ejemplo n.º 6
0
void MapTableEmitter::buildRowInstrMap() {
  for (Record *CurInstr : InstrDefs) {
    std::vector<Init*> KeyValue;
    ListInit *RowFields = InstrMapDesc.getRowFields();
    for (Init *RowField : RowFields->getValues()) {
      Init *CurInstrVal = CurInstr->getValue(RowField)->getValue();
      KeyValue.push_back(CurInstrVal);
    }

    // Collect key instructions into KeyInstrVec. Later, these instructions are
    // processed to assign column position to the instructions sharing
    // their KeyValue in RowInstrMap.
    if (isKeyColInstr(CurInstr))
      KeyInstrVec.push_back(CurInstr);

    RowInstrMap[KeyValue].push_back(CurInstr);
  }
}
Ejemplo n.º 7
0
void CallingConvEmitter::EmitCallingConv(Record *CC, std::ostream &O) {
  ListInit *CCActions = CC->getValueAsListInit("Actions");
  Counter = 0;

  O << "\n\nstatic bool " << CC->getName()
    << "(unsigned ValNo, MVT ValVT,\n"
    << std::string(CC->getName().size()+13, ' ')
    << "MVT LocVT, CCValAssign::LocInfo LocInfo,\n"
    << std::string(CC->getName().size()+13, ' ')
    << "ISD::ArgFlagsTy ArgFlags, CCState &State) {\n";
  // Emit all of the actions, in order.
  for (unsigned i = 0, e = CCActions->getSize(); i != e; ++i) {
    O << "\n";
    EmitAction(CCActions->getElementAsRecord(i), 2, O);
  }
  
  O << "\n  return true;  // CC didn't match.\n";
  O << "}\n";
}
Ejemplo n.º 8
0
static const std::vector<StringRef>
getValueAsListOfStrings(Record &R, StringRef FieldName) {
  ListInit *List = R.getValueAsListInit(FieldName);
  assert (List && "Got a null ListInit");

  std::vector<StringRef> Strings;
  Strings.reserve(List->getSize());

  for (ListInit::iterator i = List->begin(), e = List->end(); i != e; ++i) {
    assert(*i && "Got a null element in a ListInit");
    if (StringInit *S = dynamic_cast<StringInit *>(*i))
      Strings.push_back(S->getValue());
    else if (CodeInit *C = dynamic_cast<CodeInit *>(*i))
      Strings.push_back(C->getValue());
    else
      assert(false && "Got a non-string, non-code element in a ListInit");
  }

  return Strings;
}
Ejemplo n.º 9
0
void MapTableEmitter::emitMapFuncBody(raw_ostream &OS,
                                           unsigned TableSize) {

  ListInit *ColFields = InstrMapDesc.getColFields();
  const std::vector<ListInit*> &ValueCols = InstrMapDesc.getValueCols();

  // Emit binary search algorithm to locate instructions in the
  // relation table. If found, return opcode value from the appropriate column
  // of the table.
  emitBinSearch(OS, TableSize);

  if (ValueCols.size() > 1) {
    for (unsigned i = 0, e = ValueCols.size(); i < e; i++) {
      ListInit *ColumnI = ValueCols[i];
      for (unsigned j = 0, ColSize = ColumnI->size(); j < ColSize; ++j) {
        std::string ColName = ColFields->getElement(j)->getAsUnquotedString();
        OS << "  if (in" << ColName;
        OS << " == ";
        OS << ColName << "_" << ColumnI->getElement(j)->getAsUnquotedString();
        if (j < ColumnI->size() - 1) OS << " && ";
        else OS << ")\n";
      }
      OS << "    return " << InstrMapDesc.getName();
      OS << "Table[mid]["<<i+1<<"];\n";
    }
    OS << "  return -1;";
  }
  else
    OS << "  return " << InstrMapDesc.getName() << "Table[mid][1];\n";

  OS <<"}\n\n";
}
Ejemplo n.º 10
0
void MapTableEmitter::emitTablesWithFunc(raw_ostream &OS) {

  // Emit function name and the input parameters : mostly opcode value of the
  // current instruction. However, if a table has multiple columns (more than 2
  // since first column is used for the key instructions), then we also need
  // to pass another input to indicate the column to be selected.

  ListInit *ColFields = InstrMapDesc.getColFields();
  const std::vector<ListInit*> &ValueCols = InstrMapDesc.getValueCols();
  OS << "// "<< InstrMapDesc.getName() << "\nLLVM_READONLY\n";
  OS << "int "<< InstrMapDesc.getName() << "(uint16_t Opcode";
  if (ValueCols.size() > 1) {
    for (Init *CF : ColFields->getValues()) {
      std::string ColName = CF->getAsUnquotedString();
      OS << ", enum " << ColName << " in" << ColName << ") {\n";
    }
  } else { OS << ") {\n"; }

  // Emit map table.
  unsigned TableSize = emitBinSearchTable(OS);

  // Emit rest of the function body.
  emitMapFuncBody(OS, TableSize);
}
Ejemplo n.º 11
0
/// ReadNodeTypes - Read in all of the node types in the current RecordKeeper,
/// turning them into the more accessible NodeTypes data structure.
///
void InstrSelectorEmitter::ReadNodeTypes() {
  std::vector<Record*> Nodes = Records.getAllDerivedDefinitions("DagNode");
  DEBUG(std::cerr << "Getting node types: ");
  for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
    Record *Node = Nodes[i];
    
    // Translate the return type...
    NodeType::ArgResultTypes RetTy =
      NodeType::Translate(Node->getValueAsDef("RetType"));

    // Translate the arguments...
    ListInit *Args = Node->getValueAsListInit("ArgTypes");
    std::vector<NodeType::ArgResultTypes> ArgTypes;

    for (unsigned a = 0, e = Args->getSize(); a != e; ++a) {
      if (DefInit *DI = dynamic_cast<DefInit*>(Args->getElement(a)))
        ArgTypes.push_back(NodeType::Translate(DI->getDef()));
      else
        throw "In node " + Node->getName() + ", argument is not a Def!";

      if (a == 0 && ArgTypes.back() == NodeType::Arg0)
        throw "In node " + Node->getName() + ", arg 0 cannot have type 'arg0'!";
      if (a == 1 && ArgTypes.back() == NodeType::Arg1)
        throw "In node " + Node->getName() + ", arg 1 cannot have type 'arg1'!";
    }
    if ((RetTy == NodeType::Arg0 && Args->getSize() == 0) ||
        (RetTy == NodeType::Arg1 && Args->getSize() < 2))
      throw "In node " + Node->getName() +
            ", invalid return type for node with this many operands!";

    // Add the node type mapping now...
    NodeTypes[Node] = NodeType(RetTy, ArgTypes);
    DEBUG(std::cerr << Node->getName() << ", ");
  }
  DEBUG(std::cerr << "DONE!\n");
}
Ejemplo n.º 12
0
void processRecord(raw_ostream& os, Record& rec, string arch)
{
    if(!rec.getValue("GCCBuiltinName"))
        return;

    string builtinName = rec.getValueAsString("GCCBuiltinName");
    string name =  rec.getName();

    if(name.substr(0, 4) != "int_" || name.find(arch) == string::npos)
        return;

    name = name.substr(4);
    replace(name.begin(), name.end(), '_', '.');
    name = string("llvm.") + name;

    ListInit* paramsList = rec.getValueAsListInit("ParamTypes");
    vector<string> params;
    for(unsigned int i = 0; i < paramsList->getSize(); i++)
    {
        string t = dtype(paramsList->getElementAsRecord(i));
        if(t == "")
            return;

        params.push_back(t);
    }

    ListInit* retList = rec.getValueAsListInit("RetTypes");
    string ret;
    if(retList->getSize() == 0)
        ret = "void";
    else if(retList->getSize() == 1)
    {
        ret = dtype(retList->getElementAsRecord(0));
        if(ret == "")
            return;
    }
    else
        return;

    os << "pragma(LDC_intrinsic, \"" + name + "\")\n    ";
    os << ret + " " + builtinName + "(";

    if(params.size())
        os << params[0];

    for(size_t i = 1; i < params.size(); i++)
        os << ", " << params[i];

    os << ")" + attributes(rec.getValueAsListInit("Properties")) + ";\n\n";
}
Ejemplo n.º 13
0
void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
                                  Record *InstrInfo,
                         std::map<std::vector<Record*>, unsigned> &EmittedLists,
                                  std::map<Record*, unsigned> &BarriersMap,
                                  const OperandInfoMapTy &OpInfo,
                                  raw_ostream &OS) {
  int MinOperands = 0;
  if (!Inst.OperandList.empty())
    // Each logical operand can be multiple MI operands.
    MinOperands = Inst.OperandList.back().MIOperandNo +
                  Inst.OperandList.back().MINumOperands;

  OS << "  { ";
  OS << Num << ",\t" << MinOperands << ",\t"
     << Inst.NumDefs << ",\t" << getItinClassNumber(Inst.TheDef)
     << ",\t\"" << Inst.TheDef->getName() << "\", 0";

  // Emit all of the target indepedent flags...
  if (Inst.isReturn)           OS << "|(1<<TID::Return)";
  if (Inst.isBranch)           OS << "|(1<<TID::Branch)";
  if (Inst.isIndirectBranch)   OS << "|(1<<TID::IndirectBranch)";
  if (Inst.isBarrier)          OS << "|(1<<TID::Barrier)";
  if (Inst.hasDelaySlot)       OS << "|(1<<TID::DelaySlot)";
  if (Inst.isCall)             OS << "|(1<<TID::Call)";
  if (Inst.canFoldAsLoad)      OS << "|(1<<TID::FoldableAsLoad)";
  if (Inst.mayLoad)            OS << "|(1<<TID::MayLoad)";
  if (Inst.mayStore)           OS << "|(1<<TID::MayStore)";
  if (Inst.isPredicable)       OS << "|(1<<TID::Predicable)";
  if (Inst.isConvertibleToThreeAddress) OS << "|(1<<TID::ConvertibleTo3Addr)";
  if (Inst.isCommutable)       OS << "|(1<<TID::Commutable)";
  if (Inst.isTerminator)       OS << "|(1<<TID::Terminator)";
  if (Inst.isReMaterializable) OS << "|(1<<TID::Rematerializable)";
  if (Inst.isNotDuplicable)    OS << "|(1<<TID::NotDuplicable)";
  if (Inst.hasOptionalDef)     OS << "|(1<<TID::HasOptionalDef)";
  if (Inst.usesCustomDAGSchedInserter)
    OS << "|(1<<TID::UsesCustomDAGSchedInserter)";
  if (Inst.isVariadic)         OS << "|(1<<TID::Variadic)";
  if (Inst.hasSideEffects)     OS << "|(1<<TID::UnmodeledSideEffects)";
  if (Inst.isAsCheapAsAMove)   OS << "|(1<<TID::CheapAsAMove)";
  OS << ", 0";

  // Emit all of the target-specific flags...
  ListInit *LI    = InstrInfo->getValueAsListInit("TSFlagsFields");
  ListInit *Shift = InstrInfo->getValueAsListInit("TSFlagsShifts");
  if (LI->getSize() != Shift->getSize())
    throw "Lengths of " + InstrInfo->getName() +
          ":(TargetInfoFields, TargetInfoPositions) must be equal!";

  for (unsigned i = 0, e = LI->getSize(); i != e; ++i)
    emitShiftedValue(Inst.TheDef, dynamic_cast<StringInit*>(LI->getElement(i)),
                     dynamic_cast<IntInit*>(Shift->getElement(i)), OS);

  OS << ", ";

  // Emit the implicit uses and defs lists...
  std::vector<Record*> UseList = Inst.TheDef->getValueAsListOfDefs("Uses");
  if (UseList.empty())
    OS << "NULL, ";
  else
    OS << "ImplicitList" << EmittedLists[UseList] << ", ";

  std::vector<Record*> DefList = Inst.TheDef->getValueAsListOfDefs("Defs");
  if (DefList.empty())
    OS << "NULL, ";
  else
    OS << "ImplicitList" << EmittedLists[DefList] << ", ";

  std::map<Record*, unsigned>::iterator BI = BarriersMap.find(Inst.TheDef);
  if (BI == BarriersMap.end())
    OS << "NULL, ";
  else
    OS << "Barriers" << BI->second << ", ";

  // Emit the operand info.
  std::vector<std::string> OperandInfo = GetOperandInfo(Inst);
  if (OperandInfo.empty())
    OS << "0";
  else
    OS << "OperandInfo" << OpInfo.find(OperandInfo)->second;
  
  OS << " },  // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n";
}
Ejemplo n.º 14
0
CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
  TheDef = R;
  std::string DefName = R->getName();
  ModRef = ReadWriteMem;
  isOverloaded = false;
  isCommutative = false;
  canThrow = false;
  isNoReturn = false;
  isNoDuplicate = false;
  isConvergent = false;

  if (DefName.size() <= 4 ||
      std::string(DefName.begin(), DefName.begin() + 4) != "int_")
    PrintFatalError("Intrinsic '" + DefName + "' does not start with 'int_'!");

  EnumName = std::string(DefName.begin()+4, DefName.end());

  if (R->getValue("GCCBuiltinName"))  // Ignore a missing GCCBuiltinName field.
    GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
  if (R->getValue("MSBuiltinName"))   // Ignore a missing MSBuiltinName field.
    MSBuiltinName = R->getValueAsString("MSBuiltinName");

  TargetPrefix = R->getValueAsString("TargetPrefix");
  Name = R->getValueAsString("LLVMName");

  if (Name == "") {
    // If an explicit name isn't specified, derive one from the DefName.
    Name = "llvm.";

    for (unsigned i = 0, e = EnumName.size(); i != e; ++i)
      Name += (EnumName[i] == '_') ? '.' : EnumName[i];
  } else {
    // Verify it starts with "llvm.".
    if (Name.size() <= 5 ||
        std::string(Name.begin(), Name.begin() + 5) != "llvm.")
      PrintFatalError("Intrinsic '" + DefName + "'s name does not start with 'llvm.'!");
  }

  // If TargetPrefix is specified, make sure that Name starts with
  // "llvm.<targetprefix>.".
  if (!TargetPrefix.empty()) {
    if (Name.size() < 6+TargetPrefix.size() ||
        std::string(Name.begin() + 5, Name.begin() + 6 + TargetPrefix.size())
        != (TargetPrefix + "."))
      PrintFatalError("Intrinsic '" + DefName + "' does not start with 'llvm." +
        TargetPrefix + ".'!");
  }

  // Parse the list of return types.
  std::vector<MVT::SimpleValueType> OverloadedVTs;
  ListInit *TypeList = R->getValueAsListInit("RetTypes");
  for (unsigned i = 0, e = TypeList->size(); i != e; ++i) {
    Record *TyEl = TypeList->getElementAsRecord(i);
    assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
    MVT::SimpleValueType VT;
    if (TyEl->isSubClassOf("LLVMMatchType")) {
      unsigned MatchTy = TyEl->getValueAsInt("Number");
      assert(MatchTy < OverloadedVTs.size() &&
             "Invalid matching number!");
      VT = OverloadedVTs[MatchTy];
      // It only makes sense to use the extended and truncated vector element
      // variants with iAny types; otherwise, if the intrinsic is not
      // overloaded, all the types can be specified directly.
      assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
               !TyEl->isSubClassOf("LLVMTruncatedType")) ||
              VT == MVT::iAny || VT == MVT::vAny) &&
             "Expected iAny or vAny type");
    } else {
      VT = getValueType(TyEl->getValueAsDef("VT"));
    }
    if (MVT(VT).isOverloaded()) {
      OverloadedVTs.push_back(VT);
      isOverloaded = true;
    }

    // Reject invalid types.
    if (VT == MVT::isVoid)
      PrintFatalError("Intrinsic '" + DefName + " has void in result type list!");

    IS.RetVTs.push_back(VT);
    IS.RetTypeDefs.push_back(TyEl);
  }

  // Parse the list of parameter types.
  TypeList = R->getValueAsListInit("ParamTypes");
  for (unsigned i = 0, e = TypeList->size(); i != e; ++i) {
    Record *TyEl = TypeList->getElementAsRecord(i);
    assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
    MVT::SimpleValueType VT;
    if (TyEl->isSubClassOf("LLVMMatchType")) {
      unsigned MatchTy = TyEl->getValueAsInt("Number");
      assert(MatchTy < OverloadedVTs.size() &&
             "Invalid matching number!");
      VT = OverloadedVTs[MatchTy];
      // It only makes sense to use the extended and truncated vector element
      // variants with iAny types; otherwise, if the intrinsic is not
      // overloaded, all the types can be specified directly.
      assert(((!TyEl->isSubClassOf("LLVMExtendedType") &&
               !TyEl->isSubClassOf("LLVMTruncatedType") &&
               !TyEl->isSubClassOf("LLVMVectorSameWidth")) ||
              VT == MVT::iAny || VT == MVT::vAny) &&
             "Expected iAny or vAny type");
    } else
      VT = getValueType(TyEl->getValueAsDef("VT"));

    if (MVT(VT).isOverloaded()) {
      OverloadedVTs.push_back(VT);
      isOverloaded = true;
    }

    // Reject invalid types.
    if (VT == MVT::isVoid && i != e-1 /*void at end means varargs*/)
      PrintFatalError("Intrinsic '" + DefName + " has void in result type list!");

    IS.ParamVTs.push_back(VT);
    IS.ParamTypeDefs.push_back(TyEl);
  }

  // Parse the intrinsic properties.
  ListInit *PropList = R->getValueAsListInit("IntrProperties");
  for (unsigned i = 0, e = PropList->size(); i != e; ++i) {
    Record *Property = PropList->getElementAsRecord(i);
    assert(Property->isSubClassOf("IntrinsicProperty") &&
           "Expected a property!");

    if (Property->getName() == "IntrNoMem")
      ModRef = NoMem;
    else if (Property->getName() == "IntrReadMem")
      ModRef = ModRefBehavior(ModRef & ~MR_Mod);
    else if (Property->getName() == "IntrWriteMem")
      ModRef = ModRefBehavior(ModRef & ~MR_Ref);
    else if (Property->getName() == "IntrArgMemOnly")
      ModRef = ModRefBehavior(ModRef & ~MR_Anywhere);
    else if (Property->getName() == "Commutative")
      isCommutative = true;
    else if (Property->getName() == "Throws")
      canThrow = true;
    else if (Property->getName() == "IntrNoDuplicate")
      isNoDuplicate = true;
    else if (Property->getName() == "IntrConvergent")
      isConvergent = true;
    else if (Property->getName() == "IntrNoReturn")
      isNoReturn = true;
    else if (Property->isSubClassOf("NoCapture")) {
      unsigned ArgNo = Property->getValueAsInt("ArgNo");
      ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture));
    } else if (Property->isSubClassOf("Returned")) {
      unsigned ArgNo = Property->getValueAsInt("ArgNo");
      ArgumentAttributes.push_back(std::make_pair(ArgNo, Returned));
    } else if (Property->isSubClassOf("ReadOnly")) {
      unsigned ArgNo = Property->getValueAsInt("ArgNo");
      ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadOnly));
    } else if (Property->isSubClassOf("WriteOnly")) {
      unsigned ArgNo = Property->getValueAsInt("ArgNo");
      ArgumentAttributes.push_back(std::make_pair(ArgNo, WriteOnly));
    } else if (Property->isSubClassOf("ReadNone")) {
      unsigned ArgNo = Property->getValueAsInt("ArgNo");
      ArgumentAttributes.push_back(std::make_pair(ArgNo, ReadNone));
    } else
      llvm_unreachable("Unknown property!");
  }

  // Sort the argument attributes for later benefit.
  std::sort(ArgumentAttributes.begin(), ArgumentAttributes.end());
}
CodeGenIntrinsic::CodeGenIntrinsic(Record *R, CodeGenTarget *CGT) {
  TheDef = R;
  std::string DefName = R->getName();
  ModRef = WriteMem;
  isOverloaded = false;
  
  if (DefName.size() <= 4 || 
      std::string(DefName.begin(), DefName.begin()+4) != "int_")
    throw "Intrinsic '" + DefName + "' does not start with 'int_'!";
  EnumName = std::string(DefName.begin()+4, DefName.end());
  if (R->getValue("GCCBuiltinName"))  // Ignore a missing GCCBuiltinName field.
    GCCBuiltinName = R->getValueAsString("GCCBuiltinName");
  TargetPrefix   = R->getValueAsString("TargetPrefix");
  Name = R->getValueAsString("LLVMName");
  if (Name == "") {
    // If an explicit name isn't specified, derive one from the DefName.
    Name = "llvm.";
    for (unsigned i = 0, e = EnumName.size(); i != e; ++i)
      if (EnumName[i] == '_')
        Name += '.';
      else
        Name += EnumName[i];
  } else {
    // Verify it starts with "llvm.".
    if (Name.size() <= 5 || 
        std::string(Name.begin(), Name.begin()+5) != "llvm.")
      throw "Intrinsic '" + DefName + "'s name does not start with 'llvm.'!";
  }
  
  // If TargetPrefix is specified, make sure that Name starts with
  // "llvm.<targetprefix>.".
  if (!TargetPrefix.empty()) {
    if (Name.size() < 6+TargetPrefix.size() ||
        std::string(Name.begin()+5, Name.begin()+6+TargetPrefix.size()) 
        != (TargetPrefix+"."))
      throw "Intrinsic '" + DefName + "' does not start with 'llvm." + 
        TargetPrefix + ".'!";
  }
  
  // Parse the list of argument types.
  ListInit *TypeList = R->getValueAsListInit("Types");
  for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
    Record *TyEl = TypeList->getElementAsRecord(i);
    assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
    ArgTypes.push_back(TyEl->getValueAsString("TypeVal"));
    MVT::ValueType VT = getValueType(TyEl->getValueAsDef("VT"), CGT);
    isOverloaded |= VT == MVT::iAny;
    ArgVTs.push_back(VT);
    ArgTypeDefs.push_back(TyEl);
  }
  if (ArgTypes.size() == 0)
    throw "Intrinsic '"+DefName+"' needs at least a type for the ret value!";

  
  // Parse the intrinsic properties.
  ListInit *PropList = R->getValueAsListInit("Properties");
  for (unsigned i = 0, e = PropList->getSize(); i != e; ++i) {
    Record *Property = PropList->getElementAsRecord(i);
    assert(Property->isSubClassOf("IntrinsicProperty") &&
           "Expected a property!");
    
    if (Property->getName() == "IntrNoMem")
      ModRef = NoMem;
    else if (Property->getName() == "IntrReadArgMem")
      ModRef = ReadArgMem;
    else if (Property->getName() == "IntrReadMem")
      ModRef = ReadMem;
    else if (Property->getName() == "IntrWriteArgMem")
      ModRef = WriteArgMem;
    else if (Property->getName() == "IntrWriteMem")
      ModRef = WriteMem;
    else
      assert(0 && "Unknown property!");
  }
}
Ejemplo n.º 16
0
void InstrSelectorEmitter::run(std::ostream &OS) {
  // Type-check all of the node types to ensure we "understand" them.
  ReadNodeTypes();
  
  // Read in all of the nonterminals, instructions, and expanders...
  ReadNonterminals();
  ReadInstructionPatterns();
  ReadExpanderPatterns();

  // Instantiate any unresolved nonterminals with information from the context
  // that they are used in.
  InstantiateNonterminals();

  // Clear InstantiatedNTs, we don't need it anymore...
  InstantiatedNTs.clear();

  DEBUG(std::cerr << "Patterns acquired:\n");
  for (std::map<Record*, Pattern*>::iterator I = Patterns.begin(),
         E = Patterns.end(); I != E; ++I)
    if (I->second->isResolved())
      DEBUG(std::cerr << "  " << *I->second << "\n");

  CalculateComputableValues();
  
  OS << "#include \"llvm/CodeGen/MachineInstrBuilder.h\"\n";

  EmitSourceFileHeader("Instruction Selector for the " + Target.getName() +
                       " target", OS);

  // Output the slot number enums...
  OS << "\nenum { // Slot numbers...\n"
     << "  LastBuiltinSlot = ISD::NumBuiltinSlots-1, // Start numbering here\n";
  for (PatternOrganizer::iterator I = ComputableValues.begin(),
         E = ComputableValues.end(); I != E; ++I)
    OS << "  " << I->first << "_Slot,\n";
  OS << "  NumSlots\n};\n\n// Reduction value typedefs...\n";

  // Output the reduction value typedefs...
  for (PatternOrganizer::iterator I = ComputableValues.begin(),
         E = ComputableValues.end(); I != E; ++I) {

    OS << "typedef ReducedValue<unsigned, " << I->first
       << "_Slot> ReducedValue_" << I->first << ";\n";
  }

  // Output the pattern enums...
  OS << "\n\n"
     << "enum { // Patterns...\n"
     << "  NotComputed = 0,\n"
     << "  NoMatchPattern, \n";
  for (PatternOrganizer::iterator I = ComputableValues.begin(),
         E = ComputableValues.end(); I != E; ++I) {
    OS << "  // " << I->first << " patterns...\n";
    for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(),
           E = I->second.end(); J != E; ++J)
      for (unsigned i = 0, e = J->second.size(); i != e; ++i)
        OS << "  " << J->second[i]->getRecord()->getName() << "_Pattern,\n";
  }
  OS << "};\n\n";

  //===--------------------------------------------------------------------===//
  // Emit the class definition...
  //
  OS << "namespace {\n"
     << "  class " << Target.getName() << "ISel {\n"
     << "    SelectionDAG &DAG;\n"
     << "  public:\n"
     << "    " << Target.getName () << "ISel(SelectionDAG &D) : DAG(D) {}\n"
     << "    void generateCode();\n"
     << "  private:\n"
     << "    unsigned makeAnotherReg(const TargetRegisterClass *RC) {\n"
     << "      return DAG.getMachineFunction().getSSARegMap()->createVirt"
                                       "ualRegister(RC);\n"
     << "    }\n\n"
     << "    // DAG matching methods for classes... all of these methods"
                                       " return the cost\n"
     << "    // of producing a value of the specified class and type, which"
                                       " also gets\n"
     << "    // added to the DAG node.\n";

  // Output all of the matching prototypes for slots...
  for (PatternOrganizer::iterator I = ComputableValues.begin(),
         E = ComputableValues.end(); I != E; ++I)
    OS << "    unsigned Match_" << I->first << "(SelectionDAGNode *N);\n";
  OS << "\n    // DAG matching methods for DAG nodes...\n";

  // Output all of the matching prototypes for slot/node pairs
  for (PatternOrganizer::iterator I = ComputableValues.begin(),
         E = ComputableValues.end(); I != E; ++I)
    for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(),
           E = I->second.end(); J != E; ++J)
      OS << "    unsigned Match_" << I->first << "_" << getNodeName(J->first)
         << "(SelectionDAGNode *N);\n";

  // Output all of the dag reduction methods prototypes...
  OS << "\n    // DAG reduction methods...\n";
  for (PatternOrganizer::iterator I = ComputableValues.begin(),
         E = ComputableValues.end(); I != E; ++I)
    OS << "    ReducedValue_" << I->first << " *Reduce_" << I->first
       << "(SelectionDAGNode *N,\n" << std::string(27+2*I->first.size(), ' ')
       << "MachineBasicBlock *MBB);\n";
  OS << "  };\n}\n\n";

  // Emit the generateCode entry-point...
  OS << "void " << Target.getName () << "ISel::generateCode() {\n"
     << "  SelectionDAGNode *Root = DAG.getRoot();\n"
     << "  assert(Root->getValueType() == MVT::isVoid && "
                                       "\"Root of DAG produces value??\");\n\n"
     << "  std::cerr << \"\\n\";\n"
     << "  unsigned Cost = Match_Void_void(Root);\n"
     << "  if (Cost >= ~0U >> 1) {\n"
     << "    std::cerr << \"Match failed!\\n\";\n"
     << "    Root->dump();\n"
     << "    abort();\n"
     << "  }\n\n"
     << "  std::cerr << \"Total DAG Cost: \" << Cost << \"\\n\\n\";\n\n"
     << "  Reduce_Void_void(Root, 0);\n"
     << "}\n\n"
     << "//===" << std::string(70, '-') << "===//\n"
     << "//  Matching methods...\n"
     << "//\n\n";

  //===--------------------------------------------------------------------===//
  // Emit all of the matcher methods...
  //
  for (PatternOrganizer::iterator I = ComputableValues.begin(),
         E = ComputableValues.end(); I != E; ++I) {
    const std::string &SlotName = I->first;
    OS << "unsigned " << Target.getName() << "ISel::Match_" << SlotName
       << "(SelectionDAGNode *N) {\n"
       << "  assert(N->getValueType() == MVT::"
       << getEnumName((*I->second.begin()).second[0]->getTree()->getType())
       << ");\n" << "  // If we already have a cost available for " << SlotName
       << " use it!\n"
       << "  if (N->getPatternFor(" << SlotName << "_Slot))\n"
       << "    return N->getCostFor(" << SlotName << "_Slot);\n\n"
       << "  unsigned Cost;\n"
       << "  switch (N->getNodeType()) {\n"
       << "  default: Cost = ~0U >> 1;   // Match failed\n"
       << "           N->setPatternCostFor(" << SlotName << "_Slot, NoMatchPattern, Cost, NumSlots);\n"
       << "           break;\n";

    for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(),
           E = I->second.end(); J != E; ++J)
      if (!J->first->isSubClassOf("Nonterminal"))
        OS << "  case ISD::" << getNodeName(J->first) << ":\tCost = Match_"
           << SlotName << "_" << getNodeName(J->first) << "(N); break;\n";
    OS << "  }\n";  // End of the switch statement

    // Emit any patterns which have a nonterminal leaf as the RHS.  These may
    // match multiple root nodes, so they cannot be handled with the switch...
    for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(),
           E = I->second.end(); J != E; ++J)
      if (J->first->isSubClassOf("Nonterminal")) {
        OS << "  unsigned " << J->first->getName() << "_Cost = Match_"
           << getNodeName(J->first) << "(N);\n"
           << "  if (" << getNodeName(J->first) << "_Cost < Cost) Cost = "
           << getNodeName(J->first) << "_Cost;\n";
      }

    OS << "  return Cost;\n}\n\n";

    for (PatternOrganizer::NodesForSlot::iterator J = I->second.begin(),
           E = I->second.end(); J != E; ++J) {
      Record *Operator = J->first;
      bool isNonterm = Operator->isSubClassOf("Nonterminal");
      if (!isNonterm) {
        OS << "unsigned " << Target.getName() << "ISel::Match_";
        if (!isNonterm) OS << SlotName << "_";
        OS << getNodeName(Operator) << "(SelectionDAGNode *N) {\n"
           << "  unsigned Pattern = NoMatchPattern;\n"
           << "  unsigned MinCost = ~0U >> 1;\n";
        
        std::vector<std::pair<Pattern*, TreePatternNode*> > Patterns;
        for (unsigned i = 0, e = J->second.size(); i != e; ++i)
          Patterns.push_back(std::make_pair(J->second[i],
                                            J->second[i]->getTree()));
        EmitMatchCosters(OS, Patterns, "N", 2);
        
        OS << "\n  N->setPatternCostFor(" << SlotName
           << "_Slot, Pattern, MinCost, NumSlots);\n"
           << "  return MinCost;\n"
           << "}\n";
      }
    }
  }

  //===--------------------------------------------------------------------===//
  // Emit all of the reducer methods...
  //
  OS << "\n\n//===" << std::string(70, '-') << "===//\n"
     << "// Reducer methods...\n"
     << "//\n";

  for (PatternOrganizer::iterator I = ComputableValues.begin(),
         E = ComputableValues.end(); I != E; ++I) {
    const std::string &SlotName = I->first;
    OS << "ReducedValue_" << SlotName << " *" << Target.getName()
       << "ISel::Reduce_" << SlotName
       << "(SelectionDAGNode *N, MachineBasicBlock *MBB) {\n"
       << "  ReducedValue_" << SlotName << " *Val = N->hasValue<ReducedValue_"
       << SlotName << ">(" << SlotName << "_Slot);\n"
       << "  if (Val) return Val;\n"
       << "  if (N->getBB()) MBB = N->getBB();\n\n"
       << "  switch (N->getPatternFor(" << SlotName << "_Slot)) {\n";

    // Loop over all of the patterns that can produce a value for this slot...
    PatternOrganizer::NodesForSlot &NodesForSlot = I->second;
    for (PatternOrganizer::NodesForSlot::iterator J = NodesForSlot.begin(),
           E = NodesForSlot.end(); J != E; ++J)
      for (unsigned i = 0, e = J->second.size(); i != e; ++i) {
        Pattern *P = J->second[i];
        OS << "  case " << P->getRecord()->getName() << "_Pattern: {\n"
           << "    // " << *P << "\n";
        // Loop over the operands, reducing them...
        std::vector<std::pair<TreePatternNode*, std::string> > Operands;
        ReduceAllOperands(P->getTree(), "N", Operands, OS);
        
        // Now that we have reduced all of our operands, and have the values
        // that reduction produces, perform the reduction action for this
        // pattern.
        std::string Result;

        // If the pattern produces a register result, generate a new register
        // now.
        if (Record *R = P->getResult()) {
          assert(R->isSubClassOf("RegisterClass") &&
                 "Only handle register class results so far!");
          OS << "    unsigned NewReg = makeAnotherReg(" << Target.getName()
             << "::" << R->getName() << "RegisterClass);\n";
          Result = "NewReg";
          DEBUG(OS << "    std::cerr << \"%reg\" << NewReg << \" =\t\";\n");
        } else {
          DEBUG(OS << "    std::cerr << \"\t\t\";\n");
          Result = "0";
        }

        // Print out the pattern that matched...
        DEBUG(OS << "    std::cerr << \"  " << P->getRecord()->getName() <<'"');
        DEBUG(for (unsigned i = 0, e = Operands.size(); i != e; ++i)
                if (Operands[i].first->isLeaf()) {
                  Record *RV = Operands[i].first->getValueRecord();
                  assert(RV->isSubClassOf("RegisterClass") &&
                         "Only handles registers here so far!");
                  OS << " << \" %reg\" << " << Operands[i].second
                     << "->Val";
                } else {
                  OS << " << ' ' << " << Operands[i].second
                     << "->Val";
                });
        DEBUG(OS << " << \"\\n\";\n");
        
        // Generate the reduction code appropriate to the particular type of
        // pattern that this is...
        switch (P->getPatternType()) {
        case Pattern::Instruction:
          // Instruction patterns just emit a single MachineInstr, using BuildMI
          OS << "    BuildMI(MBB, " << Target.getName() << "::"
             << P->getRecord()->getName() << ", " << Operands.size();
          if (P->getResult()) OS << ", NewReg";
          OS << ")";

          for (unsigned i = 0, e = Operands.size(); i != e; ++i) {
            TreePatternNode *Op = Operands[i].first;
            if (Op->isLeaf()) {
              Record *RV = Op->getValueRecord();
              assert(RV->isSubClassOf("RegisterClass") &&
                     "Only handles registers here so far!");
              OS << ".addReg(" << Operands[i].second << "->Val)";
            } else if (Op->getOperator()->getName() == "imm") {
              OS << ".addZImm(" << Operands[i].second << "->Val)";
            } else if (Op->getOperator()->getName() == "basicblock") {
              OS << ".addMBB(" << Operands[i].second << "->Val)";
            } else {
              assert(0 && "Unknown value type!");
            }
          }
          OS << ";\n";
          break;
        case Pattern::Expander: {
          // Expander patterns emit one machine instr for each instruction in
          // the list of instructions expanded to.
          ListInit *Insts = P->getRecord()->getValueAsListInit("Result");
          for (unsigned IN = 0, e = Insts->getSize(); IN != e; ++IN) {
            DagInit *DIInst = dynamic_cast<DagInit*>(Insts->getElement(IN));
            if (!DIInst) P->error("Result list must contain instructions!");
            Record *InstRec  = DIInst->getNodeType();
            Pattern *InstPat = getPattern(InstRec);
            if (!InstPat || InstPat->getPatternType() != Pattern::Instruction)
              P->error("Instruction list must contain Instruction patterns!");
            
            bool hasResult = InstPat->getResult() != 0;
            if (InstPat->getNumArgs() != DIInst->getNumArgs()-hasResult) {
              P->error("Incorrect number of arguments specified for inst '" +
                       InstPat->getRecord()->getName() + "' in result list!");
            }

            // Start emission of the instruction...
            OS << "    BuildMI(MBB, " << Target.getName() << "::"
               << InstRec->getName() << ", "
               << DIInst->getNumArgs()-hasResult;
            // Emit register result if necessary..
            if (hasResult) {
              std::string ArgNameVal =
                getArgName(P, DIInst->getArgName(0), Operands);
              PrintExpanderOperand(DIInst->getArg(0), ArgNameVal,
                                   InstPat->getResultNode(), P, false,
                                   OS << ", ");
            }
            OS << ")";

            for (unsigned i = hasResult, e = DIInst->getNumArgs(); i != e; ++i){
              std::string ArgNameVal =
                getArgName(P, DIInst->getArgName(i), Operands);

              PrintExpanderOperand(DIInst->getArg(i), ArgNameVal,
                                   InstPat->getArg(i-hasResult), P, true, OS);
            }

            OS << ";\n";
          }
          break;
        }
        default:
          assert(0 && "Reduction of this type of pattern not implemented!");
        }

        OS << "    Val = new ReducedValue_" << SlotName << "(" << Result<<");\n"
           << "    break;\n"
           << "  }\n";
      }
    
    
    OS << "  default: assert(0 && \"Unknown " << SlotName << " pattern!\");\n"
       << "  }\n\n  N->addValue(Val);  // Do not ever recalculate this\n"
       << "  return Val;\n}\n\n";
  }
void CallingConvEmitter::EmitAction(Record *Action,
                                    unsigned Indent, std::ostream &O) {
    std::string IndentStr = std::string(Indent, ' ');

    if (Action->isSubClassOf("CCPredicateAction")) {
        O << IndentStr << "if (";

        if (Action->isSubClassOf("CCIfType")) {
            ListInit *VTs = Action->getValueAsListInit("VTs");
            for (unsigned i = 0, e = VTs->getSize(); i != e; ++i) {
                Record *VT = VTs->getElementAsRecord(i);
                if (i != 0) O << " ||\n    " << IndentStr;
                O << "LocVT == " << getEnumName(getValueType(VT));
            }

        } else if (Action->isSubClassOf("CCIf")) {
            O << Action->getValueAsString("Predicate");
        } else {
            Action->dump();
            throw "Unknown CCPredicateAction!";
        }

        O << ") {\n";
        EmitAction(Action->getValueAsDef("SubAction"), Indent+2, O);
        O << IndentStr << "}\n";
    } else {
        if (Action->isSubClassOf("CCDelegateTo")) {
            Record *CC = Action->getValueAsDef("CC");
            O << IndentStr << "if (!" << CC->getName()
              << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n"
              << IndentStr << "  return false;\n";
        } else if (Action->isSubClassOf("CCAssignToReg")) {
            ListInit *RegList = Action->getValueAsListInit("RegList");
            if (RegList->getSize() == 1) {
                O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
                O << getQualifiedName(RegList->getElementAsRecord(0)) << ")) {\n";
            } else {
                O << IndentStr << "static const unsigned RegList" << ++Counter
                  << "[] = {\n";
                O << IndentStr << "  ";
                for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
                    if (i != 0) O << ", ";
                    O << getQualifiedName(RegList->getElementAsRecord(i));
                }
                O << "\n" << IndentStr << "};\n";
                O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
                  << Counter << ", " << RegList->getSize() << ")) {\n";
            }
            O << IndentStr << "  State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
              << "Reg, LocVT, LocInfo));\n";
            O << IndentStr << "  return false;\n";
            O << IndentStr << "}\n";
        } else if (Action->isSubClassOf("CCAssignToStack")) {
            int Size = Action->getValueAsInt("Size");
            int Align = Action->getValueAsInt("Align");

            O << IndentStr << "unsigned Offset" << ++Counter
              << " = State.AllocateStack(" << Size << ", " << Align << ");\n";
            O << IndentStr << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
              << Counter << ", LocVT, LocInfo));\n";
            O << IndentStr << "return false;\n";
        } else if (Action->isSubClassOf("CCPromoteToType")) {
            Record *DestTy = Action->getValueAsDef("DestTy");
            O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
            O << IndentStr << "if (ArgFlags & ISD::ParamFlags::SExt)\n"
              << IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n"
              << IndentStr << "else if (ArgFlags & ISD::ParamFlags::ZExt)\n"
              << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n"
              << IndentStr << "else\n"
              << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n";
        } else {
            Action->dump();
            throw "Unknown CCAction!";
        }
    }
}
Ejemplo n.º 18
0
CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
  : TheDef(R), Name(R->getName()), EnumValue(-1) {
  // Rename anonymous register classes.
  if (R->getName().size() > 9 && R->getName()[9] == '.') {
    static unsigned AnonCounter = 0;
    R->setName("AnonRegClass_"+utostr(AnonCounter++));
  }

  std::vector<Record*> TypeList = R->getValueAsListOfDefs("RegTypes");
  for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
    Record *Type = TypeList[i];
    if (!Type->isSubClassOf("ValueType"))
      throw "RegTypes list member '" + Type->getName() +
        "' does not derive from the ValueType class!";
    VTs.push_back(getValueType(Type));
  }
  assert(!VTs.empty() && "RegisterClass must contain at least one ValueType!");

  // Allocation order 0 is the full set. AltOrders provides others.
  const SetTheory::RecVec *Elements = RegBank.getSets().expand(R);
  ListInit *AltOrders = R->getValueAsListInit("AltOrders");
  Orders.resize(1 + AltOrders->size());

  // Default allocation order always contains all registers.
  for (unsigned i = 0, e = Elements->size(); i != e; ++i) {
    Orders[0].push_back((*Elements)[i]);
    Members.insert(RegBank.getReg((*Elements)[i]));
  }

  // Alternative allocation orders may be subsets.
  SetTheory::RecSet Order;
  for (unsigned i = 0, e = AltOrders->size(); i != e; ++i) {
    RegBank.getSets().evaluate(AltOrders->getElement(i), Order);
    Orders[1 + i].append(Order.begin(), Order.end());
    // Verify that all altorder members are regclass members.
    while (!Order.empty()) {
      CodeGenRegister *Reg = RegBank.getReg(Order.back());
      Order.pop_back();
      if (!contains(Reg))
        throw TGError(R->getLoc(), " AltOrder register " + Reg->getName() +
                      " is not a class member");
    }
  }

  // SubRegClasses is a list<dag> containing (RC, subregindex, ...) dags.
  ListInit *SRC = R->getValueAsListInit("SubRegClasses");
  for (ListInit::const_iterator i = SRC->begin(), e = SRC->end(); i != e; ++i) {
    DagInit *DAG = dynamic_cast<DagInit*>(*i);
    if (!DAG) throw "SubRegClasses must contain DAGs";
    DefInit *DAGOp = dynamic_cast<DefInit*>(DAG->getOperator());
    Record *RCRec;
    if (!DAGOp || !(RCRec = DAGOp->getDef())->isSubClassOf("RegisterClass"))
      throw "Operator '" + DAG->getOperator()->getAsString() +
        "' in SubRegClasses is not a RegisterClass";
    // Iterate over args, all SubRegIndex instances.
    for (DagInit::const_arg_iterator ai = DAG->arg_begin(), ae = DAG->arg_end();
         ai != ae; ++ai) {
      DefInit *Idx = dynamic_cast<DefInit*>(*ai);
      Record *IdxRec;
      if (!Idx || !(IdxRec = Idx->getDef())->isSubClassOf("SubRegIndex"))
        throw "Argument '" + (*ai)->getAsString() +
          "' in SubRegClasses is not a SubRegIndex";
      if (!SubRegClasses.insert(std::make_pair(IdxRec, RCRec)).second)
        throw "SubRegIndex '" + IdxRec->getName() + "' mentioned twice";
    }
  }

  // Allow targets to override the size in bits of the RegisterClass.
  unsigned Size = R->getValueAsInt("Size");

  Namespace = R->getValueAsString("Namespace");
  SpillSize = Size ? Size : EVT(VTs[0]).getSizeInBits();
  SpillAlignment = R->getValueAsInt("Alignment");
  CopyCost = R->getValueAsInt("CopyCost");
  Allocatable = R->getValueAsBit("isAllocatable");
  AltOrderSelect = R->getValueAsCode("AltOrderSelect");
}
Ejemplo n.º 19
0
// Calculate all subregindices for Reg. Loopy subregs cause infinite recursion.
RegisterMaps::SubRegMap &RegisterMaps::inferSubRegIndices(Record *Reg) {
  SubRegMap &SRM = SubReg[Reg];
  if (!SRM.empty())
    return SRM;
  std::vector<Record*> SubRegs = Reg->getValueAsListOfDefs("SubRegs");
  std::vector<Record*> Indices = Reg->getValueAsListOfDefs("SubRegIndices");
  if (SubRegs.size() != Indices.size())
    throw "Register " + Reg->getName() + " SubRegIndices doesn't match SubRegs";

  // First insert the direct subregs and make sure they are fully indexed.
  for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) {
    if (!SRM.insert(std::make_pair(Indices[i], SubRegs[i])).second)
      throw "SubRegIndex " + Indices[i]->getName()
        + " appears twice in Register " + Reg->getName();
    inferSubRegIndices(SubRegs[i]);
  }

  // Keep track of inherited subregs and how they can be reached.
  // Register -> (SubRegIndex, SubRegIndex)
  typedef std::map<Record*, std::pair<Record*,Record*>, LessRecord> OrphanMap;
  OrphanMap Orphans;

  // Clone inherited subregs. Here the order is important - earlier subregs take
  // precedence.
  for (unsigned i = 0, e = SubRegs.size(); i != e; ++i) {
    SubRegMap &M = SubReg[SubRegs[i]];
    for (SubRegMap::iterator si = M.begin(), se = M.end(); si != se; ++si)
      if (!SRM.insert(*si).second)
        Orphans[si->second] = std::make_pair(Indices[i], si->first);
  }

  // Finally process the composites.
  ListInit *Comps = Reg->getValueAsListInit("CompositeIndices");
  for (unsigned i = 0, e = Comps->size(); i != e; ++i) {
    DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i));
    if (!Pat)
      throw "Invalid dag '" + Comps->getElement(i)->getAsString()
        + "' in CompositeIndices";
    DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator());
    if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex"))
      throw "Invalid SubClassIndex in " + Pat->getAsString();

    // Resolve list of subreg indices into R2.
    Record *R2 = Reg;
    for (DagInit::const_arg_iterator di = Pat->arg_begin(),
         de = Pat->arg_end(); di != de; ++di) {
      DefInit *IdxInit = dynamic_cast<DefInit*>(*di);
      if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex"))
        throw "Invalid SubClassIndex in " + Pat->getAsString();
      SubRegMap::const_iterator ni = SubReg[R2].find(IdxInit->getDef());
      if (ni == SubReg[R2].end())
        throw "Composite " + Pat->getAsString() + " refers to bad index in "
          + R2->getName();
      R2 = ni->second;
    }

    // Insert composite index. Allow overriding inherited indices etc.
    SRM[BaseIdxInit->getDef()] = R2;

    // R2 is now directly addressable, no longer an orphan.
    Orphans.erase(R2);
  }

  // Now, Orphans contains the inherited subregisters without a direct index.
  if (!Orphans.empty()) {
    errs() << "Error: Register " << getQualifiedName(Reg)
           << " inherited subregisters without an index:\n";
    for (OrphanMap::iterator i = Orphans.begin(), e = Orphans.end(); i != e;
         ++i) {
      errs() << "  " << getQualifiedName(i->first)
             << " = " << i->second.first->getName()
             << ", " << i->second.second->getName() << "\n";
    }
    abort();
  }
  return SRM;
}
Ejemplo n.º 20
0
CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
  TheDef = R;
  std::string DefName = R->getName();
  ModRef = WriteMem;
  isOverloaded = false;
  isCommutative = false;
  
  if (DefName.size() <= 4 || 
      std::string(DefName.begin(), DefName.begin() + 4) != "int_")
    throw "Intrinsic '" + DefName + "' does not start with 'int_'!";

  EnumName = std::string(DefName.begin()+4, DefName.end());

  if (R->getValue("GCCBuiltinName"))  // Ignore a missing GCCBuiltinName field.
    GCCBuiltinName = R->getValueAsString("GCCBuiltinName");

  TargetPrefix = R->getValueAsString("TargetPrefix");
  Name = R->getValueAsString("LLVMName");

  if (Name == "") {
    // If an explicit name isn't specified, derive one from the DefName.
    Name = "llvm.";

    for (unsigned i = 0, e = EnumName.size(); i != e; ++i)
      Name += (EnumName[i] == '_') ? '.' : EnumName[i];
  } else {
    // Verify it starts with "llvm.".
    if (Name.size() <= 5 || 
        std::string(Name.begin(), Name.begin() + 5) != "llvm.")
      throw "Intrinsic '" + DefName + "'s name does not start with 'llvm.'!";
  }
  
  // If TargetPrefix is specified, make sure that Name starts with
  // "llvm.<targetprefix>.".
  if (!TargetPrefix.empty()) {
    if (Name.size() < 6+TargetPrefix.size() ||
        std::string(Name.begin() + 5, Name.begin() + 6 + TargetPrefix.size())
        != (TargetPrefix + "."))
      throw "Intrinsic '" + DefName + "' does not start with 'llvm." +
        TargetPrefix + ".'!";
  }
  
  // Parse the list of return types.
  std::vector<MVT::SimpleValueType> OverloadedVTs;
  ListInit *TypeList = R->getValueAsListInit("RetTypes");
  for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
    Record *TyEl = TypeList->getElementAsRecord(i);
    assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
    MVT::SimpleValueType VT;
    if (TyEl->isSubClassOf("LLVMMatchType")) {
      unsigned MatchTy = TyEl->getValueAsInt("Number");
      assert(MatchTy < OverloadedVTs.size() &&
             "Invalid matching number!");
      VT = OverloadedVTs[MatchTy];
      // It only makes sense to use the extended and truncated vector element
      // variants with iAny types; otherwise, if the intrinsic is not
      // overloaded, all the types can be specified directly.
      assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
               !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
              VT == MVT::iAny || VT == MVT::vAny) &&
             "Expected iAny or vAny type");
    } else {
      VT = getValueType(TyEl->getValueAsDef("VT"));
    }
    if (EVT(VT).isOverloaded()) {
      OverloadedVTs.push_back(VT);
      isOverloaded |= true;
    }
    IS.RetVTs.push_back(VT);
    IS.RetTypeDefs.push_back(TyEl);
  }

  if (IS.RetVTs.size() == 0)
    throw "Intrinsic '"+DefName+"' needs at least a type for the ret value!";

  // Parse the list of parameter types.
  TypeList = R->getValueAsListInit("ParamTypes");
  for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
    Record *TyEl = TypeList->getElementAsRecord(i);
    assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
    MVT::SimpleValueType VT;
    if (TyEl->isSubClassOf("LLVMMatchType")) {
      unsigned MatchTy = TyEl->getValueAsInt("Number");
      assert(MatchTy < OverloadedVTs.size() &&
             "Invalid matching number!");
      VT = OverloadedVTs[MatchTy];
      // It only makes sense to use the extended and truncated vector element
      // variants with iAny types; otherwise, if the intrinsic is not
      // overloaded, all the types can be specified directly.
      assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
               !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
              VT == MVT::iAny || VT == MVT::vAny) &&
             "Expected iAny or vAny type");
    } else
      VT = getValueType(TyEl->getValueAsDef("VT"));
    if (EVT(VT).isOverloaded()) {
      OverloadedVTs.push_back(VT);
      isOverloaded |= true;
    }
    IS.ParamVTs.push_back(VT);
    IS.ParamTypeDefs.push_back(TyEl);
  }

  // Parse the intrinsic properties.
  ListInit *PropList = R->getValueAsListInit("Properties");
  for (unsigned i = 0, e = PropList->getSize(); i != e; ++i) {
    Record *Property = PropList->getElementAsRecord(i);
    assert(Property->isSubClassOf("IntrinsicProperty") &&
           "Expected a property!");
    
    if (Property->getName() == "IntrNoMem")
      ModRef = NoMem;
    else if (Property->getName() == "IntrReadArgMem")
      ModRef = ReadArgMem;
    else if (Property->getName() == "IntrReadMem")
      ModRef = ReadMem;
    else if (Property->getName() == "IntrWriteArgMem")
      ModRef = WriteArgMem;
    else if (Property->getName() == "IntrWriteMem")
      ModRef = WriteMem;
    else if (Property->getName() == "Commutative")
      isCommutative = true;
    else if (Property->isSubClassOf("NoCapture")) {
      unsigned ArgNo = Property->getValueAsInt("ArgNo");
      ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture));
    } else
      assert(0 && "Unknown property!");
  }
}
Ejemplo n.º 21
0
const CodeGenRegister::SubRegMap &
CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
  // Only compute this map once.
  if (SubRegsComplete)
    return SubRegs;
  SubRegsComplete = true;

  std::vector<Record*> SubList = TheDef->getValueAsListOfDefs("SubRegs");
  std::vector<Record*> Indices = TheDef->getValueAsListOfDefs("SubRegIndices");
  if (SubList.size() != Indices.size())
    throw TGError(TheDef->getLoc(), "Register " + getName() +
                  " SubRegIndices doesn't match SubRegs");

  // First insert the direct subregs and make sure they are fully indexed.
  for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
    CodeGenRegister *SR = RegBank.getReg(SubList[i]);
    if (!SubRegs.insert(std::make_pair(Indices[i], SR)).second)
      throw TGError(TheDef->getLoc(), "SubRegIndex " + Indices[i]->getName() +
                    " appears twice in Register " + getName());
  }

  // Keep track of inherited subregs and how they can be reached.
  SmallVector<Orphan, 8> Orphans;

  // Clone inherited subregs and place duplicate entries on Orphans.
  // Here the order is important - earlier subregs take precedence.
  for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
    CodeGenRegister *SR = RegBank.getReg(SubList[i]);
    const SubRegMap &Map = SR->getSubRegs(RegBank);

    // Add this as a super-register of SR now all sub-registers are in the list.
    // This creates a topological ordering, the exact order depends on the
    // order getSubRegs is called on all registers.
    SR->SuperRegs.push_back(this);

    for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE;
         ++SI) {
      if (!SubRegs.insert(*SI).second)
        Orphans.push_back(Orphan(SI->second, Indices[i], SI->first));

      // Noop sub-register indexes are possible, so avoid duplicates.
      if (SI->second != SR)
        SI->second->SuperRegs.push_back(this);
    }
  }

  // Process the composites.
  ListInit *Comps = TheDef->getValueAsListInit("CompositeIndices");
  for (unsigned i = 0, e = Comps->size(); i != e; ++i) {
    DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i));
    if (!Pat)
      throw TGError(TheDef->getLoc(), "Invalid dag '" +
                    Comps->getElement(i)->getAsString() +
                    "' in CompositeIndices");
    DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator());
    if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex"))
      throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " +
                    Pat->getAsString());

    // Resolve list of subreg indices into R2.
    CodeGenRegister *R2 = this;
    for (DagInit::const_arg_iterator di = Pat->arg_begin(),
         de = Pat->arg_end(); di != de; ++di) {
      DefInit *IdxInit = dynamic_cast<DefInit*>(*di);
      if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex"))
        throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " +
                      Pat->getAsString());
      const SubRegMap &R2Subs = R2->getSubRegs(RegBank);
      SubRegMap::const_iterator ni = R2Subs.find(IdxInit->getDef());
      if (ni == R2Subs.end())
        throw TGError(TheDef->getLoc(), "Composite " + Pat->getAsString() +
                      " refers to bad index in " + R2->getName());
      R2 = ni->second;
    }

    // Insert composite index. Allow overriding inherited indices etc.
    SubRegs[BaseIdxInit->getDef()] = R2;

    // R2 is no longer an orphan.
    for (unsigned j = 0, je = Orphans.size(); j != je; ++j)
      if (Orphans[j].SubReg == R2)
          Orphans[j].SubReg = 0;
  }

  // Now Orphans contains the inherited subregisters without a direct index.
  // Create inferred indexes for all missing entries.
  for (unsigned i = 0, e = Orphans.size(); i != e; ++i) {
    Orphan &O = Orphans[i];
    if (!O.SubReg)
      continue;
    SubRegs[RegBank.getCompositeSubRegIndex(O.First, O.Second, true)] =
      O.SubReg;
  }
  return SubRegs;
}
Ejemplo n.º 22
0
void CallingConvEmitter::EmitAction(Record *Action,
                                    unsigned Indent, std::ostream &O) {
  std::string IndentStr = std::string(Indent, ' ');
  
  if (Action->isSubClassOf("CCPredicateAction")) {
    O << IndentStr << "if (";
    
    if (Action->isSubClassOf("CCIfType")) {
      ListInit *VTs = Action->getValueAsListInit("VTs");
      for (unsigned i = 0, e = VTs->getSize(); i != e; ++i) {
        Record *VT = VTs->getElementAsRecord(i);
        if (i != 0) O << " ||\n    " << IndentStr;
        O << "LocVT == " << getEnumName(getValueType(VT));
      }

    } else if (Action->isSubClassOf("CCIf")) {
      O << Action->getValueAsString("Predicate");
    } else {
      Action->dump();
      throw "Unknown CCPredicateAction!";
    }
    
    O << ") {\n";
    EmitAction(Action->getValueAsDef("SubAction"), Indent+2, O);
    O << IndentStr << "}\n";
  } else {
    if (Action->isSubClassOf("CCDelegateTo")) {
      Record *CC = Action->getValueAsDef("CC");
      O << IndentStr << "if (!" << CC->getName()
        << "(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State))\n"
        << IndentStr << "  return false;\n";
    } else if (Action->isSubClassOf("CCAssignToReg")) {
      ListInit *RegList = Action->getValueAsListInit("RegList");
      if (RegList->getSize() == 1) {
        O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
        O << getQualifiedName(RegList->getElementAsRecord(0)) << ")) {\n";
      } else {
        O << IndentStr << "static const unsigned RegList" << ++Counter
          << "[] = {\n";
        O << IndentStr << "  ";
        for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
          if (i != 0) O << ", ";
          O << getQualifiedName(RegList->getElementAsRecord(i));
        }
        O << "\n" << IndentStr << "};\n";
        O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
          << Counter << ", " << RegList->getSize() << ")) {\n";
      }
      O << IndentStr << "  State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
        << "Reg, LocVT, LocInfo));\n";
      O << IndentStr << "  return false;\n";
      O << IndentStr << "}\n";
    } else if (Action->isSubClassOf("CCAssignToRegWithShadow")) {
      ListInit *RegList = Action->getValueAsListInit("RegList");
      ListInit *ShadowRegList = Action->getValueAsListInit("ShadowRegList");
      if (ShadowRegList->getSize() >0 &&
          ShadowRegList->getSize() != RegList->getSize())
        throw "Invalid length of list of shadowed registers";

      if (RegList->getSize() == 1) {
        O << IndentStr << "if (unsigned Reg = State.AllocateReg(";
        O << getQualifiedName(RegList->getElementAsRecord(0));
        O << ", " << getQualifiedName(ShadowRegList->getElementAsRecord(0));
        O << ")) {\n";
      } else {
        unsigned RegListNumber = ++Counter;
        unsigned ShadowRegListNumber = ++Counter;

        O << IndentStr << "static const unsigned RegList" << RegListNumber
          << "[] = {\n";
        O << IndentStr << "  ";
        for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
          if (i != 0) O << ", ";
          O << getQualifiedName(RegList->getElementAsRecord(i));
        }
        O << "\n" << IndentStr << "};\n";

        O << IndentStr << "static const unsigned RegList"
          << ShadowRegListNumber << "[] = {\n";
        O << IndentStr << "  ";
        for (unsigned i = 0, e = ShadowRegList->getSize(); i != e; ++i) {
          if (i != 0) O << ", ";
          O << getQualifiedName(ShadowRegList->getElementAsRecord(i));
        }
        O << "\n" << IndentStr << "};\n";

        O << IndentStr << "if (unsigned Reg = State.AllocateReg(RegList"
          << RegListNumber << ", " << "RegList" << ShadowRegListNumber
          << ", " << RegList->getSize() << ")) {\n";
      }
      O << IndentStr << "  State.addLoc(CCValAssign::getReg(ValNo, ValVT, "
        << "Reg, LocVT, LocInfo));\n";
      O << IndentStr << "  return false;\n";
      O << IndentStr << "}\n";
    } else if (Action->isSubClassOf("CCAssignToStack")) {
      int Size = Action->getValueAsInt("Size");
      int Align = Action->getValueAsInt("Align");

      O << IndentStr << "unsigned Offset" << ++Counter
        << " = State.AllocateStack(";
      if (Size)
        O << Size << ", ";
      else
        O << "\n" << IndentStr << "  State.getTarget().getTargetData()"
          "->getTypePaddedSize(LocVT.getTypeForMVT()), ";
      if (Align)
        O << Align;
      else
        O << "\n" << IndentStr << "  State.getTarget().getTargetData()"
          "->getABITypeAlignment(LocVT.getTypeForMVT())";
      O << ");\n" << IndentStr
        << "State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset"
        << Counter << ", LocVT, LocInfo));\n";
      O << IndentStr << "return false;\n";
    } else if (Action->isSubClassOf("CCPromoteToType")) {
      Record *DestTy = Action->getValueAsDef("DestTy");
      O << IndentStr << "LocVT = " << getEnumName(getValueType(DestTy)) <<";\n";
      O << IndentStr << "if (ArgFlags.isSExt())\n"
        << IndentStr << IndentStr << "LocInfo = CCValAssign::SExt;\n"
        << IndentStr << "else if (ArgFlags.isZExt())\n"
        << IndentStr << IndentStr << "LocInfo = CCValAssign::ZExt;\n"
        << IndentStr << "else\n"
        << IndentStr << IndentStr << "LocInfo = CCValAssign::AExt;\n";
    } else if (Action->isSubClassOf("CCPassByVal")) {
      int Size = Action->getValueAsInt("Size");
      int Align = Action->getValueAsInt("Align");
      O << IndentStr
        << "State.HandleByVal(ValNo, ValVT, LocVT, LocInfo, "
        << Size << ", " << Align << ", ArgFlags);\n";
      O << IndentStr << "return false;\n";
    } else {
      Action->dump();
      throw "Unknown CCAction!";
    }
  }
}
Ejemplo n.º 23
0
const CodeGenRegister::SubRegMap &
CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
  // Only compute this map once.
  if (SubRegsComplete)
    return SubRegs;
  SubRegsComplete = true;

  std::vector<Record*> SubList = TheDef->getValueAsListOfDefs("SubRegs");
  std::vector<Record*> IdxList = TheDef->getValueAsListOfDefs("SubRegIndices");
  if (SubList.size() != IdxList.size())
    throw TGError(TheDef->getLoc(), "Register " + getName() +
                  " SubRegIndices doesn't match SubRegs");

  // First insert the direct subregs and make sure they are fully indexed.
  SmallVector<CodeGenSubRegIndex*, 8> Indices;
  for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
    CodeGenRegister *SR = RegBank.getReg(SubList[i]);
    CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(IdxList[i]);
    Indices.push_back(Idx);
    if (!SubRegs.insert(std::make_pair(Idx, SR)).second)
      throw TGError(TheDef->getLoc(), "SubRegIndex " + Idx->getName() +
                    " appears twice in Register " + getName());
  }

  // Keep track of inherited subregs and how they can be reached.
  SmallPtrSet<CodeGenRegister*, 8> Orphans;

  // Clone inherited subregs and place duplicate entries in Orphans.
  // Here the order is important - earlier subregs take precedence.
  for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
    CodeGenRegister *SR = RegBank.getReg(SubList[i]);
    const SubRegMap &Map = SR->getSubRegs(RegBank);

    // Add this as a super-register of SR now all sub-registers are in the list.
    // This creates a topological ordering, the exact order depends on the
    // order getSubRegs is called on all registers.
    SR->SuperRegs.push_back(this);

    for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE;
         ++SI) {
      if (!SubRegs.insert(*SI).second)
        Orphans.insert(SI->second);

      // Noop sub-register indexes are possible, so avoid duplicates.
      if (SI->second != SR)
        SI->second->SuperRegs.push_back(this);
    }
  }

  // Expand any composed subreg indices.
  // If dsub_2 has ComposedOf = [qsub_1, dsub_0], and this register has a
  // qsub_1 subreg, add a dsub_2 subreg.  Keep growing Indices and process
  // expanded subreg indices recursively.
  for (unsigned i = 0; i != Indices.size(); ++i) {
    CodeGenSubRegIndex *Idx = Indices[i];
    const CodeGenSubRegIndex::CompMap &Comps = Idx->getComposites();
    CodeGenRegister *SR = SubRegs[Idx];
    const SubRegMap &Map = SR->getSubRegs(RegBank);

    // Look at the possible compositions of Idx.
    // They may not all be supported by SR.
    for (CodeGenSubRegIndex::CompMap::const_iterator I = Comps.begin(),
           E = Comps.end(); I != E; ++I) {
      SubRegMap::const_iterator SRI = Map.find(I->first);
      if (SRI == Map.end())
        continue; // Idx + I->first doesn't exist in SR.
      // Add I->second as a name for the subreg SRI->second, assuming it is
      // orphaned, and the name isn't already used for something else.
      if (SubRegs.count(I->second) || !Orphans.erase(SRI->second))
        continue;
      // We found a new name for the orphaned sub-register.
      SubRegs.insert(std::make_pair(I->second, SRI->second));
      Indices.push_back(I->second);
    }
  }

  // Process the composites.
  ListInit *Comps = TheDef->getValueAsListInit("CompositeIndices");
  for (unsigned i = 0, e = Comps->size(); i != e; ++i) {
    DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i));
    if (!Pat)
      throw TGError(TheDef->getLoc(), "Invalid dag '" +
                    Comps->getElement(i)->getAsString() +
                    "' in CompositeIndices");
    DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator());
    if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex"))
      throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " +
                    Pat->getAsString());
    CodeGenSubRegIndex *BaseIdx = RegBank.getSubRegIdx(BaseIdxInit->getDef());

    // Resolve list of subreg indices into R2.
    CodeGenRegister *R2 = this;
    for (DagInit::const_arg_iterator di = Pat->arg_begin(),
         de = Pat->arg_end(); di != de; ++di) {
      DefInit *IdxInit = dynamic_cast<DefInit*>(*di);
      if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex"))
        throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " +
                      Pat->getAsString());
      CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(IdxInit->getDef());
      const SubRegMap &R2Subs = R2->getSubRegs(RegBank);
      SubRegMap::const_iterator ni = R2Subs.find(Idx);
      if (ni == R2Subs.end())
        throw TGError(TheDef->getLoc(), "Composite " + Pat->getAsString() +
                      " refers to bad index in " + R2->getName());
      R2 = ni->second;
    }

    // Insert composite index. Allow overriding inherited indices etc.
    SubRegs[BaseIdx] = R2;

    // R2 is no longer an orphan.
    Orphans.erase(R2);
  }

  // Now Orphans contains the inherited subregisters without a direct index.
  // Create inferred indexes for all missing entries.
  // Work backwards in the Indices vector in order to compose subregs bottom-up.
  // Consider this subreg sequence:
  //
  //   qsub_1 -> dsub_0 -> ssub_0
  //
  // The qsub_1 -> dsub_0 composition becomes dsub_2, so the ssub_0 register
  // can be reached in two different ways:
  //
  //   qsub_1 -> ssub_0
  //   dsub_2 -> ssub_0
  //
  // We pick the latter composition because another register may have [dsub_0,
  // dsub_1, dsub_2] subregs without neccessarily having a qsub_1 subreg.  The
  // dsub_2 -> ssub_0 composition can be shared.
  while (!Indices.empty() && !Orphans.empty()) {
    CodeGenSubRegIndex *Idx = Indices.pop_back_val();
    CodeGenRegister *SR = SubRegs[Idx];
    const SubRegMap &Map = SR->getSubRegs(RegBank);
    for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE;
         ++SI)
      if (Orphans.erase(SI->second))
        SubRegs[RegBank.getCompositeSubRegIndex(Idx, SI->first)] = SI->second;
  }

  // Initialize RegUnitList. A register with no subregisters creates its own
  // unit. Otherwise, it inherits all its subregister's units. Because
  // getSubRegs is called recursively, this processes the register hierarchy in
  // postorder.
  //
  // TODO: We currently assume all register units correspond to a named "leaf"
  // register. We should also unify register units for ad-hoc register
  // aliases. This can be done by iteratively merging units for aliasing
  // registers using a worklist.
  assert(RegUnits.empty() && "Should only initialize RegUnits once");
  if (SubRegs.empty()) {
    RegUnits.push_back(RegBank.newRegUnit());
  }
  else {
    for (SubRegMap::const_iterator I = SubRegs.begin(), E = SubRegs.end();
         I != E; ++I) {
      // Strangely a register may have itself as a subreg (self-cycle) e.g. XMM.
      CodeGenRegister *SR = I->second;
      if (SR == this) {
        if (RegUnits.empty())
          RegUnits.push_back(RegBank.newRegUnit());
        continue;
      }
      // Merge the subregister's units into this register's RegUnits.
      mergeRegUnits(RegUnits, SR->RegUnits);
    }
  }
  return SubRegs;
}