diff options
Diffstat (limited to 'lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp')
| -rw-r--r-- | lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp | 40 | 
1 files changed, 27 insertions, 13 deletions
diff --git a/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp b/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp index e2edb924d4d2..8619cbdcb5ee 100644 --- a/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp +++ b/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp @@ -8,7 +8,7 @@  //===----------------------------------------------------------------------===//  ///  /// \file -/// \brief This file converts any remaining registers into WebAssembly locals. +/// This file converts any remaining registers into WebAssembly locals.  ///  /// After register stackification and register coloring, convert non-stackified  /// registers into locals, inserting explicit get_local and set_local @@ -60,6 +60,9 @@ public:  } // end anonymous namespace  char WebAssemblyExplicitLocals::ID = 0; +INITIALIZE_PASS(WebAssemblyExplicitLocals, DEBUG_TYPE, +                "Convert registers to WebAssembly locals", false, false) +  FunctionPass *llvm::createWebAssemblyExplicitLocals() {    return new WebAssemblyExplicitLocals();  } @@ -86,6 +89,8 @@ static unsigned getDropOpcode(const TargetRegisterClass *RC) {      return WebAssembly::DROP_F64;    if (RC == &WebAssembly::V128RegClass)      return WebAssembly::DROP_V128; +  if (RC == &WebAssembly::EXCEPT_REFRegClass) +    return WebAssembly::DROP_EXCEPT_REF;    llvm_unreachable("Unexpected register class");  } @@ -101,6 +106,8 @@ static unsigned getGetLocalOpcode(const TargetRegisterClass *RC) {      return WebAssembly::GET_LOCAL_F64;    if (RC == &WebAssembly::V128RegClass)      return WebAssembly::GET_LOCAL_V128; +  if (RC == &WebAssembly::EXCEPT_REFRegClass) +    return WebAssembly::GET_LOCAL_EXCEPT_REF;    llvm_unreachable("Unexpected register class");  } @@ -116,6 +123,8 @@ static unsigned getSetLocalOpcode(const TargetRegisterClass *RC) {      return WebAssembly::SET_LOCAL_F64;    if (RC == &WebAssembly::V128RegClass)      return WebAssembly::SET_LOCAL_V128; +  if (RC == &WebAssembly::EXCEPT_REFRegClass) +    return WebAssembly::SET_LOCAL_EXCEPT_REF;    llvm_unreachable("Unexpected register class");  } @@ -131,6 +140,8 @@ static unsigned getTeeLocalOpcode(const TargetRegisterClass *RC) {      return WebAssembly::TEE_LOCAL_F64;    if (RC == &WebAssembly::V128RegClass)      return WebAssembly::TEE_LOCAL_V128; +  if (RC == &WebAssembly::EXCEPT_REFRegClass) +    return WebAssembly::TEE_LOCAL_EXCEPT_REF;    llvm_unreachable("Unexpected register class");  } @@ -144,6 +155,8 @@ static MVT typeForRegClass(const TargetRegisterClass *RC) {      return MVT::f32;    if (RC == &WebAssembly::F64RegClass)      return MVT::f64; +  if (RC == &WebAssembly::EXCEPT_REFRegClass) +    return MVT::ExceptRef;    llvm_unreachable("unrecognized register class");  } @@ -168,19 +181,14 @@ static MachineInstr *FindStartOfTree(MachineOperand &MO,  }  bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) { -  DEBUG(dbgs() << "********** Make Locals Explicit **********\n" -                  "********** Function: " -               << MF.getName() << '\n'); +  LLVM_DEBUG(dbgs() << "********** Make Locals Explicit **********\n" +                       "********** Function: " +                    << MF.getName() << '\n');    // Disable this pass if directed to do so.    if (DisableWebAssemblyExplicitLocals)      return false; -  // Disable this pass if we aren't doing direct wasm object emission. -  if (MF.getSubtarget<WebAssemblySubtarget>() -        .getTargetTriple().isOSBinFormatELF()) -    return false; -    bool Changed = false;    MachineRegisterInfo &MRI = MF.getRegInfo();    WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>(); @@ -218,7 +226,7 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {        MachineInstr &MI = *I++;        assert(!WebAssembly::isArgument(MI)); -      if (MI.isDebugValue() || MI.isLabel()) +      if (MI.isDebugInstr() || MI.isLabel())          continue;        // Replace tee instructions with tee_local. The difference is that tee @@ -271,8 +279,11 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {            }            if (UseEmpty[TargetRegisterInfo::virtReg2Index(OldReg)]) {              unsigned Opc = getDropOpcode(RC); -            BuildMI(MBB, InsertPt, MI.getDebugLoc(), TII->get(Opc)) -                .addReg(NewReg); +            MachineInstr *Drop = +                BuildMI(MBB, InsertPt, MI.getDebugLoc(), TII->get(Opc)) +                    .addReg(NewReg); +            // After the drop instruction, this reg operand will not be used +            Drop->getOperand(0).setIsKill();            } else {              unsigned LocalId = getLocalId(Reg2Local, CurLocal, OldReg);              unsigned Opc = getSetLocalOpcode(RC); @@ -281,6 +292,9 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {                  .addReg(NewReg);            }            MI.getOperand(0).setReg(NewReg); +          // This register operand is now being used by the inserted drop +          // instruction, so make it undead. +          MI.getOperand(0).setIsDead(false);            MFI.stackifyVReg(NewReg);            Changed = true;          } @@ -362,7 +376,7 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {    // Assert that all registers have been stackified at this point.    for (const MachineBasicBlock &MBB : MF) {      for (const MachineInstr &MI : MBB) { -      if (MI.isDebugValue() || MI.isLabel()) +      if (MI.isDebugInstr() || MI.isLabel())          continue;        for (const MachineOperand &MO : MI.explicit_operands()) {          assert(  | 
