[llvm-commits] [llvm] r55085 - in /llvm/trunk: include/llvm/CodeGen/FastISel.h lib/CodeGen/SelectionDAG/FastISel.cpp lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

Dan Gohman gohman at apple.com
Wed Aug 20 17:00:46 PDT 2008


Hi Evan,

Comments inline below.

On Aug 20, 2008, at 3:45 PM, Evan Cheng wrote:

> Author: evancheng
> Date: Wed Aug 20 17:45:34 2008
> New Revision: 55085
>
> URL: http://llvm.org/viewvc/llvm-project?rev=55085&view=rev
> Log:
> First cut, un-optimized (and untested) fast isel lowering of  
> GetElementPtrInst.
>
> Modified:
>    llvm/trunk/include/llvm/CodeGen/FastISel.h
>    llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
>    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
>
> Modified: llvm/trunk/include/llvm/CodeGen/FastISel.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/FastISel.h?rev=55085&r1=55084&r2=55085&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/include/llvm/CodeGen/FastISel.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/FastISel.h Wed Aug 20 17:45:34  
> 2008
> @@ -23,7 +23,9 @@
> class MachineBasicBlock;
> class MachineFunction;
> class MachineRegisterInfo;
> +class TargetData;
> class TargetInstrInfo;
> +class TargetLowering;
> class TargetRegisterClass;
>
> /// FastISel - This is a fast-path instruction selection class that
> @@ -33,7 +35,9 @@
>   MachineBasicBlock *MBB;
>   MachineFunction &MF;
>   MachineRegisterInfo &MRI;
> +  const TargetData &TD;
>   const TargetInstrInfo &TII;
> +  TargetLowering &TLI;
>
> public:
>   /// SelectInstructions - Do "fast" instruction selection over the
> @@ -72,6 +76,29 @@
>                                ISD::NodeType Opcode,
>                                unsigned Op0, unsigned Op1);
>
> +  /// FastEmit_i - This method is called by target-independent code
> +  /// to request that an instruction with the given type which  
> materialize
> +  /// the specified immediate value.
> +  virtual unsigned FastEmit_i(MVT::SimpleValueType VT, uint64_t Imm);
> +
> +  /// FastEmit_ri - This method is called by target-independent code
> +  /// to request that an instruction with the given type, opcode, and
> +  /// register and immediate operands be emitted.
> +  ///
> +  virtual unsigned FastEmit_ri(MVT::SimpleValueType VT,
> +                               ISD::NodeType Opcode,
> +                               unsigned Op0, uint64_t Imm,
> +                               MVT::SimpleValueType ImmType);
> +
> +  /// FastEmit_ri_ - This method is a wrapper of FastEmit_ri. It  
> first tries
> +  /// to emit an instruction with an immediate operand using  
> FastEmit_ri.
> +  /// If that fails, it materializes the immediate into a register  
> and try
> +  /// FastEmit_rr instead.
> +  unsigned FastEmit_ri_(MVT::SimpleValueType VT,
> +                        ISD::NodeType Opcode,
> +                        unsigned Op0, uint64_t Imm,
> +                        MVT::SimpleValueType ImmType);
> +
>   /// FastEmitInst_ - Emit a MachineInstr with no operands and a
>   /// result register in the given register class.
>   ///
>
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp?rev=55085&r1=55084&r2=55085&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/FastISel.cpp Wed Aug 20  
> 17:45:34 2008
> @@ -15,7 +15,9 @@
> #include "llvm/CodeGen/FastISel.h"
> #include "llvm/CodeGen/MachineInstrBuilder.h"
> #include "llvm/CodeGen/MachineRegisterInfo.h"
> +#include "llvm/Target/TargetData.h"
> #include "llvm/Target/TargetInstrInfo.h"
> +#include "llvm/Target/TargetLowering.h"
> #include "llvm/Target/TargetMachine.h"
> using namespace llvm;
>
> @@ -48,8 +50,81 @@
>
> bool FastISel::SelectGetElementPtr(Instruction *I,
>                                    DenseMap<const Value*, unsigned>  
> &ValueMap) {
> -  // TODO: implement me
> -  return false;
> +  unsigned N = ValueMap[I->getOperand(0)];
> +  if (N == 0)
> +    // Unhandled operand. Halt "fast" selection and bail.
> +    return false;
> +
> +  const Type *Ty = I->getOperand(0)->getType();
> +  MVT VT = MVT::getMVT(Ty, /*HandleUnknown=*/true);

HandleUnknown should be false here; the type of a GEP is a pointer,
which shouldn't ever be unknown.

>
> +  MVT::SimpleValueType PtrVT = TLI.getPointerTy().getSimpleVT();

PtrVT and VT will have the same value here. Can one of them be  
eliminated?

>
> +
> +  for (GetElementPtrInst::op_iterator OI = I->op_begin()+1, E = I- 
> >op_end();
> +       OI != E; ++OI) {
> +    Value *Idx = *OI;
> +    if (const StructType *StTy = dyn_cast<StructType>(Ty)) {
> +      unsigned Field = cast<ConstantInt>(Idx)->getZExtValue();
> +      if (Field) {
> +        // N = N + Offset
> +        uint64_t Offs = TD.getStructLayout(StTy)- 
> >getElementOffset(Field);
> +        // FIXME: This can be optimized by combining the add with a
> +        // subsequent one.
> +        N = FastEmit_ri(VT.getSimpleVT(), ISD::ADD, N, Offs, PtrVT);
> +        if (N == 0)
> +          // Unhandled operand. Halt "fast" selection and bail.
> +          return false;
> +      }
> +      Ty = StTy->getElementType(Field);
> +    } else {
> +      Ty = cast<SequentialType>(Ty)->getElementType();
> +
> +      // If this is a constant subscript, handle it quickly.
> +      if (ConstantInt *CI = dyn_cast<ConstantInt>(Idx)) {
> +        if (CI->getZExtValue() == 0) continue;
> +        uint64_t Offs =
> +          TD.getABITypeSize(Ty)*cast<ConstantInt>(CI)- 
> >getSExtValue();
> +        N = FastEmit_ri(VT.getSimpleVT(), ISD::ADD, N, Offs, PtrVT);
> +        if (N == 0)
> +          // Unhandled operand. Halt "fast" selection and bail.
> +          return false;
> +        continue;
> +      }
> +
> +      // N = N + Idx * ElementSize;
> +      uint64_t ElementSize = TD.getABITypeSize(Ty);
> +      unsigned IdxN = ValueMap[Idx];
> +      if (IdxN == 0)
> +        // Unhandled operand. Halt "fast" selection and bail.
> +        return false;
> +
> +      // If the index is smaller or larger than intptr_t, truncate  
> or extend
> +      // it.
> +      MVT IdxVT = MVT::getMVT(Idx->getType(), /*HandleUnknown=*/ 
> true);

Same as above with HandleUnknown.

>
> +      if (IdxVT.bitsLT(VT))
> +        IdxN = FastEmit_r(VT.getSimpleVT(), ISD::SIGN_EXTEND, IdxN);
> +      else if (IdxVT.bitsGT(VT))
> +        IdxN = FastEmit_r(VT.getSimpleVT(), ISD::TRUNCATE, IdxN);
> +      if (IdxN == 0)
> +        // Unhandled operand. Halt "fast" selection and bail.
> +        return false;
> +
> +      // FIXME: If multiple is power of two, turn it into a shift.  
> The
> +      // optimization should be in FastEmit_ri?
> +      IdxN = FastEmit_ri(VT.getSimpleVT(), ISD::MUL, IdxN,
> +                         ElementSize, PtrVT);

How would converting a multiply into a shift benefit compile time?

Dan




More information about the llvm-commits mailing list