diff options
| author | Eli Friedman <eli.friedman@gmail.com> | 2011-04-27 01:45:07 +0000 | 
|---|---|---|
| committer | Eli Friedman <eli.friedman@gmail.com> | 2011-04-27 01:45:07 +0000 | 
| commit | bcc69141463827adfec45cdd177fe39b8b289713 (patch) | |
| tree | 5511078058712b45a0459e125b74e94043a1ff27 /llvm/lib/Target/X86/X86FastISel.cpp | |
| parent | ae124da62537e89f615a062015d355e89369a0d9 (diff) | |
| download | bcm5719-llvm-bcc69141463827adfec45cdd177fe39b8b289713.tar.gz bcm5719-llvm-bcc69141463827adfec45cdd177fe39b8b289713.zip | |
Refactor out code to fast-isel a memcpy operation with a small constant
length.  (I'm planning to use this to implement byval.)
llvm-svn: 130274
Diffstat (limited to 'llvm/lib/Target/X86/X86FastISel.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/X86FastISel.cpp | 72 | 
1 files changed, 40 insertions, 32 deletions
| diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp index 257b4741cee..2a5c6282d73 100644 --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -132,6 +132,9 @@ private:    }    bool isTypeLegal(const Type *Ty, MVT &VT, bool AllowI1 = false); + +  bool TryEmitSmallMemcpy(X86AddressMode DestAM, +                          X86AddressMode SrcAM, uint64_t Len);  };  } // end anonymous namespace. @@ -1323,6 +1326,40 @@ bool X86FastISel::X86SelectExtractValue(const Instruction *I) {    return false;  } +bool X86FastISel::TryEmitSmallMemcpy(X86AddressMode DestAM, +                                     X86AddressMode SrcAM, uint64_t Len) { +  // Make sure we don't bloat code by inlining very large memcpy's. +  bool i64Legal = TLI.isTypeLegal(MVT::i64); +  if (Len > (i64Legal ? 32 : 16)) return false; + +  // We don't care about alignment here since we just emit integer accesses. +  while (Len) { +    MVT VT; +    if (Len >= 8 && i64Legal) +      VT = MVT::i64; +    else if (Len >= 4) +      VT = MVT::i32; +    else if (Len >= 2) +      VT = MVT::i16; +    else { +      assert(Len == 1); +      VT = MVT::i8; +    } + +    unsigned Reg; +    bool RV = X86FastEmitLoad(VT, SrcAM, Reg); +    RV &= X86FastEmitStore(VT, Reg, DestAM); +    assert(RV && "Failed to emit load or store??"); + +    unsigned Size = VT.getSizeInBits()/8; +    Len -= Size; +    DestAM.Disp += Size; +    SrcAM.Disp += Size; +  } + +  return true; +} +  bool X86FastISel::X86VisitIntrinsicCall(const IntrinsicInst &I) {    // FIXME: Handle more intrinsics.    switch (I.getIntrinsicID()) { @@ -1332,45 +1369,16 @@ bool X86FastISel::X86VisitIntrinsicCall(const IntrinsicInst &I) {      // Don't handle volatile or variable length memcpys.      if (MCI.isVolatile() || !isa<ConstantInt>(MCI.getLength()))        return false; -     -    // Don't inline super long memcpys.  We could lower these to a memcpy call, -    // but we might as well bail out. +      uint64_t Len = cast<ConstantInt>(MCI.getLength())->getZExtValue(); -    bool i64Legal = TLI.isTypeLegal(MVT::i64); -    if (Len > (i64Legal ? 32 : 16)) return false;      // Get the address of the dest and source addresses.      X86AddressMode DestAM, SrcAM;      if (!X86SelectAddress(MCI.getRawDest(), DestAM) ||          !X86SelectAddress(MCI.getRawSource(), SrcAM))        return false; -     -    // We don't care about alignment here since we just emit integer accesses. -    while (Len) { -      MVT VT; -      if (Len >= 8 && i64Legal) -        VT = MVT::i64; -      else if (Len >= 4) -        VT = MVT::i32; -      else if (Len >= 2) -        VT = MVT::i16; -      else { -        assert(Len == 1); -        VT = MVT::i8; -      } -       -      unsigned Reg; -      bool RV = X86FastEmitLoad(VT, SrcAM, Reg); -      RV &= X86FastEmitStore(VT, Reg, DestAM); -      assert(RV && "Failed to emit load or store??"); -       -      unsigned Size = VT.getSizeInBits()/8; -      Len -= Size; -      DestAM.Disp += Size; -      SrcAM.Disp += Size; -    } -     -    return true; + +    return TryEmitSmallMemcpy(DestAM, SrcAM, Len);    }    case Intrinsic::stackprotector: { | 

