Ejemplo n.º 1
0
static void writeSPToMemory(unsigned SrcReg, MachineFunction &MF,
                            MachineBasicBlock &MBB,
                            MachineBasicBlock::iterator &InsertAddr,
                            MachineBasicBlock::iterator &InsertStore,
                            const DebugLoc &DL) {
    const char *ES = "__stack_pointer";
    auto *SPSymbol = MF.createExternalSymbolName(ES);
    MachineRegisterInfo &MRI = MF.getRegInfo();
    const TargetRegisterClass *PtrRC =
        MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
    unsigned Zero = MRI.createVirtualRegister(PtrRC);
    const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();

    BuildMI(MBB, InsertAddr, DL, TII->get(WebAssembly::CONST_I32), Zero)
    .addImm(0);
    MachineMemOperand *MMO = MF.getMachineMemOperand(
                                 MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES)),
                                 MachineMemOperand::MOStore, 4, 4);
    BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::STORE_I32))
    .addImm(2)  // p2align
    .addExternalSymbol(SPSymbol)
    .addReg(Zero)
    .addReg(SrcReg)
    .addMemOperand(MMO);
}
Ejemplo n.º 2
0
void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF,
        MachineBasicBlock &MBB) const {
    // TODO: Do ".setMIFlag(MachineInstr::FrameSetup)" on emitted instructions
    auto &MFI = MF.getFrameInfo();
    assert(MFI.getCalleeSavedInfo().empty() &&
           "WebAssembly should not have callee-saved registers");

    if (!needsSP(MF, MFI)) return;
    uint64_t StackSize = MFI.getStackSize();

    const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
    auto &MRI = MF.getRegInfo();

    auto InsertPt = MBB.begin();
    DebugLoc DL;

    const TargetRegisterClass *PtrRC =
        MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
    unsigned Zero = MRI.createVirtualRegister(PtrRC);
    unsigned SPReg = MRI.createVirtualRegister(PtrRC);
    const char *ES = "__stack_pointer";
    auto *SPSymbol = MF.createExternalSymbolName(ES);
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), Zero)
    .addImm(0);
    MachineMemOperand *LoadMMO = MF.getMachineMemOperand(
                                     MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES)),
                                     MachineMemOperand::MOLoad, 4, 4);
    // Load the SP value.
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::LOAD_I32),
            StackSize ? SPReg : (unsigned)WebAssembly::SP32)
    .addImm(2)       // p2align
    .addExternalSymbol(SPSymbol)
    .addReg(Zero)    // addr
    .addMemOperand(LoadMMO);

    if (StackSize) {
        // Subtract the frame size
        unsigned OffsetReg = MRI.createVirtualRegister(PtrRC);
        BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), OffsetReg)
        .addImm(StackSize);
        BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::SUB_I32),
                WebAssembly::SP32)
        .addReg(SPReg)
        .addReg(OffsetReg);
    }
    if (hasFP(MF)) {
        // Unlike most conventional targets (where FP points to the saved FP),
        // FP points to the bottom of the fixed-size locals, so we can use positive
        // offsets in load/store instructions.
        BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::COPY),
                WebAssembly::FP32)
        .addReg(WebAssembly::SP32);
    }
    if (StackSize && needsSPWriteback(MF, MFI)) {
        writeSPToMemory(WebAssembly::SP32, MF, MBB, InsertPt, InsertPt, DL);
    }
}
void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF,
                                            MachineBasicBlock &MBB) const {
  // TODO: Do ".setMIFlag(MachineInstr::FrameSetup)" on emitted instructions
  auto &MFI = MF.getFrameInfo();
  assert(MFI.getCalleeSavedInfo().empty() &&
         "WebAssembly should not have callee-saved registers");

  if (!needsSP(MF, MFI)) return;
  uint64_t StackSize = MFI.getStackSize();

  const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
  auto &MRI = MF.getRegInfo();

  auto InsertPt = MBB.begin();
  while (InsertPt != MBB.end() && WebAssembly::isArgument(*InsertPt))
    ++InsertPt;
  DebugLoc DL;

  const TargetRegisterClass *PtrRC =
      MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
  unsigned SPReg = WebAssembly::SP32;
  if (StackSize)
    SPReg = MRI.createVirtualRegister(PtrRC);

  const char *ES = "__stack_pointer";
  auto *SPSymbol = MF.createExternalSymbolName(ES);
  if (MF.getSubtarget<WebAssemblySubtarget>()
        .getTargetTriple().isOSBinFormatELF()) {
    unsigned Zero = MRI.createVirtualRegister(PtrRC);

    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), Zero)
        .addImm(0);
    MachineMemOperand *LoadMMO = MF.getMachineMemOperand(
        MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES)),
        MachineMemOperand::MOLoad, 4, 4);
    // Load the SP value.
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::LOAD_I32), SPReg)
        .addImm(2)       // p2align
        .addExternalSymbol(SPSymbol)
        .addReg(Zero)    // addr
        .addMemOperand(LoadMMO);
  } else {
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::GET_GLOBAL_I32), SPReg)
        .addExternalSymbol(SPSymbol);
  }

  bool HasBP = hasBP(MF);
  if (HasBP) {
    auto FI = MF.getInfo<WebAssemblyFunctionInfo>();
    unsigned BasePtr = MRI.createVirtualRegister(PtrRC);
    FI->setBasePointerVreg(BasePtr);
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::COPY), BasePtr)
        .addReg(SPReg);
  }
  if (StackSize) {
    // Subtract the frame size
    unsigned OffsetReg = MRI.createVirtualRegister(PtrRC);
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), OffsetReg)
        .addImm(StackSize);
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::SUB_I32),
            WebAssembly::SP32)
        .addReg(SPReg)
        .addReg(OffsetReg);
  }
  if (HasBP) {
    unsigned BitmaskReg = MRI.createVirtualRegister(PtrRC);
    unsigned Alignment = MFI.getMaxAlignment();
    assert((1u << countTrailingZeros(Alignment)) == Alignment &&
      "Alignment must be a power of 2");
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), BitmaskReg)
        .addImm((int)~(Alignment - 1));
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::AND_I32),
            WebAssembly::SP32)
        .addReg(WebAssembly::SP32)
        .addReg(BitmaskReg);
  }
  if (hasFP(MF)) {
    // Unlike most conventional targets (where FP points to the saved FP),
    // FP points to the bottom of the fixed-size locals, so we can use positive
    // offsets in load/store instructions.
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::COPY),
            WebAssembly::FP32)
        .addReg(WebAssembly::SP32);
  }
  if (StackSize && needsSPWriteback(MF, MFI)) {
    writeSPToMemory(WebAssembly::SP32, MF, MBB, InsertPt, InsertPt, DL);
  }
}
Ejemplo n.º 4
0
MachinePointerInfo MachinePointerInfo::getStack(MachineFunction &MF,
                                                int64_t Offset, uint8_t ID) {
  return MachinePointerInfo(MF.getPSVManager().getStack(), Offset, ID);
}
Ejemplo n.º 5
0
MachinePointerInfo MachinePointerInfo::getCapTable(MachineFunction &MF) {
  return MachinePointerInfo(MF.getPSVManager().getCapTable());
}
Ejemplo n.º 6
0
/// getFixedStack - Return a MachinePointerInfo record that refers to the
/// the specified FrameIndex.
MachinePointerInfo MachinePointerInfo::getFixedStack(MachineFunction &MF,
                                                     int FI, int64_t Offset) {
  return MachinePointerInfo(MF.getPSVManager().getFixedStack(FI), Offset);
}
Ejemplo n.º 7
0
/// getConstantPool - Return a MachinePointerInfo record that refers to the
/// constant pool.
MachinePointerInfo MachinePointerInfo::getConstantPool(MachineFunction &MF) {
  return MachinePointerInfo(MF.getPSVManager().getConstantPool());
}
Ejemplo n.º 8
0
/// Colorslots - Color all spill stack slots and rewrite all frameindex machine
/// operands in the function.
bool StackSlotColoring::ColorSlots(MachineFunction &MF) {
    unsigned NumObjs = MFI->getObjectIndexEnd();
    SmallVector<int, 16> SlotMapping(NumObjs, -1);
    SmallVector<float, 16> SlotWeights(NumObjs, 0.0);
    SmallVector<SmallVector<int, 4>, 16> RevMap(NumObjs);
    BitVector UsedColors(NumObjs);

    DEBUG(dbgs() << "Color spill slot intervals:\n");
    bool Changed = false;
    for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
        LiveInterval *li = SSIntervals[i];
        int SS = TargetRegisterInfo::stackSlot2Index(li->reg);
        int NewSS = ColorSlot(li);
        assert(NewSS >= 0 && "Stack coloring failed?");
        SlotMapping[SS] = NewSS;
        RevMap[NewSS].push_back(SS);
        SlotWeights[NewSS] += li->weight;
        UsedColors.set(NewSS);
        Changed |= (SS != NewSS);
    }

    DEBUG(dbgs() << "\nSpill slots after coloring:\n");
    for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i) {
        LiveInterval *li = SSIntervals[i];
        int SS = TargetRegisterInfo::stackSlot2Index(li->reg);
        li->weight = SlotWeights[SS];
    }
    // Sort them by new weight.
    std::stable_sort(SSIntervals.begin(), SSIntervals.end(), IntervalSorter());

#ifndef NDEBUG
    for (unsigned i = 0, e = SSIntervals.size(); i != e; ++i)
        DEBUG(SSIntervals[i]->dump());
    DEBUG(dbgs() << '\n');
#endif

    if (!Changed)
        return false;

    // Rewrite all MachineMemOperands.
    for (unsigned SS = 0, SE = SSRefs.size(); SS != SE; ++SS) {
        int NewFI = SlotMapping[SS];
        if (NewFI == -1 || (NewFI == (int)SS))
            continue;

        const PseudoSourceValue *NewSV = MF.getPSVManager().getFixedStack(NewFI);
        SmallVectorImpl<MachineMemOperand *> &RefMMOs = SSRefs[SS];
        for (unsigned i = 0, e = RefMMOs.size(); i != e; ++i)
            RefMMOs[i]->setValue(NewSV);
    }

    // Rewrite all MO_FrameIndex operands.  Look for dead stores.
    for (MachineFunction::iterator MBBI = MF.begin(), E = MF.end();
            MBBI != E; ++MBBI) {
        MachineBasicBlock *MBB = &*MBBI;
        for (MachineBasicBlock::iterator MII = MBB->begin(), EE = MBB->end();
                MII != EE; ++MII)
            RewriteInstruction(MII, SlotMapping, MF);
        RemoveDeadStores(MBB);
    }

    // Delete unused stack slots.
    while (NextColor != -1) {
        DEBUG(dbgs() << "Removing unused stack object fi#" << NextColor << "\n");
        MFI->RemoveStackObject(NextColor);
        NextColor = AllColors.find_next(NextColor);
    }

    return true;
}