[llvm-commits] [llvm] r85850 - in /llvm/trunk/lib/Target/ARM: ARM.h ARMBaseInstrInfo.cpp ARMTargetMachine.cpp NEONMoveFix.cpp

Evan Cheng evan.cheng at apple.com
Mon Nov 2 18:13:57 PST 2009


On Nov 2, 2009, at 5:04 PM, Anton Korobeynikov wrote:

> 
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp (original)
> +++ llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp Mon Nov  2 19:04:26 2009
> @@ -112,8 +112,11 @@
> bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM,
>                                           CodeGenOpt::Level OptLevel) {
>   // FIXME: temporarily disabling load / store optimization pass for Thumb1.
> -  if (OptLevel != CodeGenOpt::None && !Subtarget.isThumb1Only())
> -    PM.add(createIfConverterPass());
> +  if (OptLevel != CodeGenOpt::None) {
> +    if (!Subtarget.isThumb1Only())
> +      PM.add(createIfConverterPass());
> +    PM.add(createNEONMoveFixPass());

Please make sure this is run only when NEON is available.

Evan

> +  }
> 
>   if (Subtarget.isThumb2()) {
>     PM.add(createThumb2ITBlockPass());
> 
> Added: llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp?rev=85850&view=auto
> 
> ==============================================================================
> --- llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp (added)
> +++ llvm/trunk/lib/Target/ARM/NEONMoveFix.cpp Mon Nov  2 19:04:26 2009
> @@ -0,0 +1,144 @@
> +//===-- NEONMoveFix.cpp - Convert vfp reg-reg moves into neon ---*- C++ -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#define DEBUG_TYPE "neon-mov-fix"
> +#include "ARM.h"
> +#include "ARMMachineFunctionInfo.h"
> +#include "ARMInstrInfo.h"
> +#include "llvm/CodeGen/MachineInstr.h"
> +#include "llvm/CodeGen/MachineInstrBuilder.h"
> +#include "llvm/CodeGen/MachineFunctionPass.h"
> +#include "llvm/ADT/Statistic.h"
> +#include "llvm/Support/Debug.h"
> +#include "llvm/Support/raw_ostream.h"
> +using namespace llvm;
> +
> +STATISTIC(NumVMovs, "Number of reg-reg moves converted");
> +
> +namespace {
> +  struct NEONMoveFixPass : public MachineFunctionPass {
> +    static char ID;
> +    NEONMoveFixPass() : MachineFunctionPass(&ID) {}
> +
> +    virtual bool runOnMachineFunction(MachineFunction &Fn);
> +
> +    virtual const char *getPassName() const {
> +      return "NEON reg-reg move conversion";
> +    }
> +
> +  private:
> +    const TargetRegisterInfo *TRI;
> +    const ARMBaseInstrInfo *TII;
> +    const ARMSubtarget *Subtarget;
> +
> +    typedef DenseMap<unsigned, const MachineInstr*> RegMap;
> +
> +    bool InsertMoves(MachineBasicBlock &MBB);
> +  };
> +  char NEONMoveFixPass::ID = 0;
> +}
> +
> +bool NEONMoveFixPass::InsertMoves(MachineBasicBlock &MBB) {
> +  RegMap Defs;
> +  bool Modified = false;
> +
> +  // Walk over MBB tracking the def points of the registers.
> +  MachineBasicBlock::iterator MII = MBB.begin(), E = MBB.end();
> +  MachineBasicBlock::iterator NextMII;
> +  for (; MII != E; MII = NextMII) {
> +    NextMII = next(MII);
> +    MachineInstr *MI = &*MII;
> +
> +    if (MI->getOpcode() == ARM::FCPYD &&
> +        !TII->isPredicated(MI)) {
> +      unsigned SrcReg = MI->getOperand(1).getReg();
> +      // If we do not found an instruction defining the reg, this means the
> +      // register should be live-in for this BB. It's always to better to use
> +      // NEON reg-reg moves.
> +      unsigned Domain = ARMII::DomainNEON;
> +      RegMap::iterator DefMI = Defs.find(SrcReg);
> +      if (DefMI != Defs.end()) {
> +        Domain = DefMI->second->getDesc().TSFlags & ARMII::DomainMask;
> +        // Instructions in general domain are subreg accesses.
> +        // Map them to NEON reg-reg moves.
> +        if (Domain == ARMII::DomainGeneral)
> +          Domain = ARMII::DomainNEON;
> +      }
> +
> +      if ((Domain & ARMII::DomainNEON) && Subtarget->hasNEON()) {
> +        // Convert FCPYD to VMOVD.
> +        unsigned DestReg = MI->getOperand(0).getReg();
> +
> +        DEBUG({errs() << "vmov convert: "; MI->dump();});
> +
> +        // It's safe to ignore imp-defs / imp-uses here, since:
> +        //  - We're running late, no intelligent condegen passes should be run
> +        //    afterwards
> +        //  - The imp-defs / imp-uses are superregs only, we don't care about
> +        //    them.
> +        BuildMI(MBB, *MI, MI->getDebugLoc(),
> +                TII->get(ARM::VMOVD), DestReg).addReg(SrcReg);
> +        MBB.erase(MI);
> +        MachineBasicBlock::iterator I = prior(NextMII);
> +        MI = &*I;
> +
> +        DEBUG({errs() << "        into: "; MI->dump();});
> +
> +        Modified = true;
> +        ++NumVMovs;
> +      } else {
> +        assert((Domain & ARMII::DomainVFP ||
> +                !Subtarget->hasNEON()) && "Invalid domain!");
> +        // Do nothing.
> +      }
> +    }
> +
> +    // Update def information.
> +    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
> +      const MachineOperand& MO = MI->getOperand(i);
> +      if (!MO.isReg() || !MO.isDef())
> +        continue;
> +      unsigned MOReg = MO.getReg();
> +
> +      Defs[MOReg] = MI;
> +      // Catch subregs as well.
> +      for (const unsigned *R = TRI->getSubRegisters(MOReg); *R; ++R)
> +        Defs[*R] = MI;
> +    }
> +  }
> +
> +  return Modified;
> +}
> +
> +bool NEONMoveFixPass::runOnMachineFunction(MachineFunction &Fn) {
> +  ARMFunctionInfo *AFI = Fn.getInfo<ARMFunctionInfo>();
> +  const TargetMachine &TM = Fn.getTarget();
> +
> +  if (AFI->isThumbFunction())
> +    return false;
> +
> +  TRI = TM.getRegisterInfo();
> +  Subtarget = &TM.getSubtarget<ARMSubtarget>();
> +  TII = static_cast<const ARMBaseInstrInfo*>(TM.getInstrInfo());
> +
> +  bool Modified = false;
> +  for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
> +       ++MFI) {
> +    MachineBasicBlock &MBB = *MFI;
> +    Modified |= InsertMoves(MBB);
> +  }
> +
> +  return Modified;
> +}
> +
> +/// createNEONMoveFixPass - Returns an instance of the NEON reg-reg moves fix
> +/// pass.
> +FunctionPass *llvm::createNEONMoveFixPass() {
> +  return new NEONMoveFixPass();
> +}
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits





More information about the llvm-commits mailing list