Example #1
0
/// EmitDbgValue - Generate machine instruction for a dbg_value node.
///
MachineInstr *
InstrEmitter::EmitDbgValue(SDDbgValue *SD,
                           DenseMap<SDValue, unsigned> &VRBaseMap) {
  uint64_t Offset = SD->getOffset();
  MDNode* MDPtr = SD->getMDPtr();
  DebugLoc DL = SD->getDebugLoc();

  if (SD->getKind() == SDDbgValue::FRAMEIX) {
    // Stack address; this needs to be lowered in target-dependent fashion.
    // EmitTargetCodeForFrameDebugValue is responsible for allocation.
    return BuildMI(*MF, DL, TII->get(TargetOpcode::DBG_VALUE))
        .addFrameIndex(SD->getFrameIx()).addImm(Offset).addMetadata(MDPtr);
  }
  // Otherwise, we're going to create an instruction here.
  const MCInstrDesc &II = TII->get(TargetOpcode::DBG_VALUE);
  MachineInstrBuilder MIB = BuildMI(*MF, DL, II);
  if (SD->getKind() == SDDbgValue::SDNODE) {
    SDNode *Node = SD->getSDNode();
    SDValue Op = SDValue(Node, SD->getResNo());
    // It's possible we replaced this SDNode with other(s) and therefore
    // didn't generate code for it.  It's better to catch these cases where
    // they happen and transfer the debug info, but trying to guarantee that
    // in all cases would be very fragile; this is a safeguard for any
    // that were missed.
    DenseMap<SDValue, unsigned>::iterator I = VRBaseMap.find(Op);
    if (I==VRBaseMap.end())
      MIB.addReg(0U);       // undef
    else
      AddOperand(MIB, Op, (*MIB).getNumOperands(), &II, VRBaseMap,
                 /*IsDebug=*/true, /*IsClone=*/false, /*IsCloned=*/false);
  } else if (SD->getKind() == SDDbgValue::CONST) {
    const Value *V = SD->getConst();
    if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
      if (CI->getBitWidth() > 64)
        MIB.addCImm(CI);
      else
        MIB.addImm(CI->getSExtValue());
    } else if (const ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
      MIB.addFPImm(CF);
    } else {
      // Could be an Undef.  In any case insert an Undef so we can see what we
      // dropped.
      MIB.addReg(0U);
    }
  } else {
    // Insert an Undef so we can see what we dropped.
    MIB.addReg(0U);
  }

  if (Offset != 0) // Indirect addressing.
    MIB.addImm(Offset);
  else
    MIB.addReg(0U, RegState::Debug);

  MIB.addMetadata(MDPtr);

  return &*MIB;
}
Example #2
0
MachineInstr *
InstrEmitter::EmitDbgLabel(SDDbgLabel *SD) {
  MDNode *Label = SD->getLabel();
  DebugLoc DL = SD->getDebugLoc();
  assert(cast<DILabel>(Label)->isValidLocationForIntrinsic(DL) &&
         "Expected inlined-at fields to agree");

  const MCInstrDesc &II = TII->get(TargetOpcode::DBG_LABEL);
  MachineInstrBuilder MIB = BuildMI(*MF, DL, II);
  MIB.addMetadata(Label);

  return &*MIB;
}
Example #3
0
/// EmitSpecialNode - Generate machine code for a target-independent node and
/// needed dependencies.
void InstrEmitter::
EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
                DenseMap<SDValue, unsigned> &VRBaseMap) {
  switch (Node->getOpcode()) {
  default:
#ifndef NDEBUG
    Node->dump();
#endif
    llvm_unreachable("This target-independent node should have been selected!");
  case ISD::EntryToken:
    llvm_unreachable("EntryToken should have been excluded from the schedule!");
  case ISD::MERGE_VALUES:
  case ISD::TokenFactor: // fall thru
    break;
  case ISD::CopyToReg: {
    unsigned SrcReg;
    SDValue SrcVal = Node->getOperand(2);
    if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(SrcVal))
      SrcReg = R->getReg();
    else
      SrcReg = getVR(SrcVal, VRBaseMap);

    unsigned DestReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
    if (SrcReg == DestReg) // Coalesced away the copy? Ignore.
      break;

    BuildMI(*MBB, InsertPos, Node->getDebugLoc(), TII->get(TargetOpcode::COPY),
            DestReg).addReg(SrcReg);
    break;
  }
  case ISD::CopyFromReg: {
    unsigned SrcReg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
    EmitCopyFromReg(Node, 0, IsClone, IsCloned, SrcReg, VRBaseMap);
    break;
  }
  case ISD::EH_LABEL:
  case ISD::ANNOTATION_LABEL: {
    unsigned Opc = (Node->getOpcode() == ISD::EH_LABEL)
                       ? TargetOpcode::EH_LABEL
                       : TargetOpcode::ANNOTATION_LABEL;
    MCSymbol *S = cast<LabelSDNode>(Node)->getLabel();
    BuildMI(*MBB, InsertPos, Node->getDebugLoc(),
            TII->get(Opc)).addSym(S);
    break;
  }

  case ISD::LIFETIME_START:
  case ISD::LIFETIME_END: {
    unsigned TarOp = (Node->getOpcode() == ISD::LIFETIME_START) ?
    TargetOpcode::LIFETIME_START : TargetOpcode::LIFETIME_END;

    FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Node->getOperand(1));
    BuildMI(*MBB, InsertPos, Node->getDebugLoc(), TII->get(TarOp))
    .addFrameIndex(FI->getIndex());
    break;
  }

  case ISD::INLINEASM: {
    unsigned NumOps = Node->getNumOperands();
    if (Node->getOperand(NumOps-1).getValueType() == MVT::Glue)
      --NumOps;  // Ignore the glue operand.

    // Create the inline asm machine instruction.
    MachineInstrBuilder MIB = BuildMI(*MF, Node->getDebugLoc(),
                                      TII->get(TargetOpcode::INLINEASM));

    // Add the asm string as an external symbol operand.
    SDValue AsmStrV = Node->getOperand(InlineAsm::Op_AsmString);
    const char *AsmStr = cast<ExternalSymbolSDNode>(AsmStrV)->getSymbol();
    MIB.addExternalSymbol(AsmStr);

    // Add the HasSideEffect, isAlignStack, AsmDialect, MayLoad and MayStore
    // bits.
    int64_t ExtraInfo =
      cast<ConstantSDNode>(Node->getOperand(InlineAsm::Op_ExtraInfo))->
                          getZExtValue();
    MIB.addImm(ExtraInfo);

    // Remember to operand index of the group flags.
    SmallVector<unsigned, 8> GroupIdx;

    // Remember registers that are part of early-clobber defs.
    SmallVector<unsigned, 8> ECRegs;

    // Add all of the operand registers to the instruction.
    for (unsigned i = InlineAsm::Op_FirstOperand; i != NumOps;) {
      unsigned Flags =
        cast<ConstantSDNode>(Node->getOperand(i))->getZExtValue();
      const unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags);

      GroupIdx.push_back(MIB->getNumOperands());
      MIB.addImm(Flags);
      ++i;  // Skip the ID value.

      switch (InlineAsm::getKind(Flags)) {
      default: llvm_unreachable("Bad flags!");
        case InlineAsm::Kind_RegDef:
        for (unsigned j = 0; j != NumVals; ++j, ++i) {
          unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
          // FIXME: Add dead flags for physical and virtual registers defined.
          // For now, mark physical register defs as implicit to help fast
          // regalloc. This makes inline asm look a lot like calls.
          MIB.addReg(Reg, RegState::Define |
                  getImplRegState(TargetRegisterInfo::isPhysicalRegister(Reg)));
        }
        break;
      case InlineAsm::Kind_RegDefEarlyClobber:
      case InlineAsm::Kind_Clobber:
        for (unsigned j = 0; j != NumVals; ++j, ++i) {
          unsigned Reg = cast<RegisterSDNode>(Node->getOperand(i))->getReg();
          MIB.addReg(Reg, RegState::Define | RegState::EarlyClobber |
                  getImplRegState(TargetRegisterInfo::isPhysicalRegister(Reg)));
          ECRegs.push_back(Reg);
        }
        break;
      case InlineAsm::Kind_RegUse:  // Use of register.
      case InlineAsm::Kind_Imm:  // Immediate.
      case InlineAsm::Kind_Mem:  // Addressing mode.
        // The addressing mode has been selected, just add all of the
        // operands to the machine instruction.
        for (unsigned j = 0; j != NumVals; ++j, ++i)
          AddOperand(MIB, Node->getOperand(i), 0, nullptr, VRBaseMap,
                     /*IsDebug=*/false, IsClone, IsCloned);

        // Manually set isTied bits.
        if (InlineAsm::getKind(Flags) == InlineAsm::Kind_RegUse) {
          unsigned DefGroup = 0;
          if (InlineAsm::isUseOperandTiedToDef(Flags, DefGroup)) {
            unsigned DefIdx = GroupIdx[DefGroup] + 1;
            unsigned UseIdx = GroupIdx.back() + 1;
            for (unsigned j = 0; j != NumVals; ++j)
              MIB->tieOperands(DefIdx + j, UseIdx + j);
          }
        }
        break;
      }
    }

    // GCC inline assembly allows input operands to also be early-clobber
    // output operands (so long as the operand is written only after it's
    // used), but this does not match the semantics of our early-clobber flag.
    // If an early-clobber operand register is also an input operand register,
    // then remove the early-clobber flag.
    for (unsigned Reg : ECRegs) {
      if (MIB->readsRegister(Reg, TRI)) {
        MachineOperand *MO = MIB->findRegisterDefOperand(Reg, false, TRI);
        assert(MO && "No def operand for clobbered register?");
        MO->setIsEarlyClobber(false);
      }
    }

    // Get the mdnode from the asm if it exists and add it to the instruction.
    SDValue MDV = Node->getOperand(InlineAsm::Op_MDNode);
    const MDNode *MD = cast<MDNodeSDNode>(MDV)->getMD();
    if (MD)
      MIB.addMetadata(MD);

    MBB->insert(InsertPos, MIB);
    break;
  }
  }
}
Example #4
0
/// EmitDbgValue - Generate machine instruction for a dbg_value node.
///
MachineInstr *
InstrEmitter::EmitDbgValue(SDDbgValue *SD,
                           DenseMap<SDValue, unsigned> &VRBaseMap) {
  MDNode *Var = SD->getVariable();
  MDNode *Expr = SD->getExpression();
  DebugLoc DL = SD->getDebugLoc();
  assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
         "Expected inlined-at fields to agree");

  if (SD->getKind() == SDDbgValue::FRAMEIX) {
    // Stack address; this needs to be lowered in target-dependent fashion.
    // EmitTargetCodeForFrameDebugValue is responsible for allocation.
    auto FrameMI = BuildMI(*MF, DL, TII->get(TargetOpcode::DBG_VALUE))
                       .addFrameIndex(SD->getFrameIx());
    if (SD->isIndirect())
      // Push [fi + 0] onto the DIExpression stack.
      FrameMI.addImm(0);
    else
      // Push fi onto the DIExpression stack.
      FrameMI.addReg(0);
    return FrameMI.addMetadata(Var).addMetadata(Expr);
  }
  // Otherwise, we're going to create an instruction here.
  const MCInstrDesc &II = TII->get(TargetOpcode::DBG_VALUE);
  MachineInstrBuilder MIB = BuildMI(*MF, DL, II);
  if (SD->getKind() == SDDbgValue::SDNODE) {
    SDNode *Node = SD->getSDNode();
    SDValue Op = SDValue(Node, SD->getResNo());
    // It's possible we replaced this SDNode with other(s) and therefore
    // didn't generate code for it.  It's better to catch these cases where
    // they happen and transfer the debug info, but trying to guarantee that
    // in all cases would be very fragile; this is a safeguard for any
    // that were missed.
    DenseMap<SDValue, unsigned>::iterator I = VRBaseMap.find(Op);
    if (I==VRBaseMap.end())
      MIB.addReg(0U);       // undef
    else
      AddOperand(MIB, Op, (*MIB).getNumOperands(), &II, VRBaseMap,
                 /*IsDebug=*/true, /*IsClone=*/false, /*IsCloned=*/false);
  } else if (SD->getKind() == SDDbgValue::VREG) {
    MIB.addReg(SD->getVReg(), RegState::Debug);
  } else if (SD->getKind() == SDDbgValue::CONST) {
    const Value *V = SD->getConst();
    if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
      if (CI->getBitWidth() > 64)
        MIB.addCImm(CI);
      else
        MIB.addImm(CI->getSExtValue());
    } else if (const ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
      MIB.addFPImm(CF);
    } else {
      // Could be an Undef.  In any case insert an Undef so we can see what we
      // dropped.
      MIB.addReg(0U);
    }
  } else {
    // Insert an Undef so we can see what we dropped.
    MIB.addReg(0U);
  }

  // Indirect addressing is indicated by an Imm as the second parameter.
  if (SD->isIndirect())
    MIB.addImm(0U);
  else
    MIB.addReg(0U, RegState::Debug);

  MIB.addMetadata(Var);
  MIB.addMetadata(Expr);

  return &*MIB;
}