Split memcpy/memset/memmove intrinsics into i32/i64 versions, resolving
authorChris Lattner <sabre@nondot.org>
Fri, 3 Mar 2006 00:00:25 +0000 (00:00 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 3 Mar 2006 00:00:25 +0000 (00:00 +0000)
PR709, and paving the way for future progress.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26476 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Assembly/AutoUpgrade.h
include/llvm/IntrinsicInst.h
include/llvm/Intrinsics.h
lib/Analysis/DataStructure/Local.cpp
lib/CodeGen/IntrinsicLowering.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

index b8f9e22cca4775393fa9e2d15114fdbdee13d834..0bc69a8a4e71083a5cb1c800bd83f7438bd02af0 100644 (file)
@@ -24,12 +24,6 @@ namespace llvm {
   class Value;
   class BasicBlock;
 
-  /// This function determines if the \p Name provides is a name for which the
-  /// auto-upgrade to a non-overloaded name applies.
-  /// @returns True if the function name is upgradeable, false otherwise.
-  /// @brief Determine if a name is an upgradeable intrinsic name.
-  bool IsUpgradeableIntrinsicName(const std::string& Name);
-
   /// This function inspects the Function \p F to see if it is an old overloaded
   /// intrinsic. If it is, the Function's name is changed to add a suffix that
   /// indicates the kind of arguments or result that it accepts. In LLVM release
@@ -56,14 +50,10 @@ namespace llvm {
   /// non-overloaded names. This function inspects the CallInst \p CI to see 
   /// if it is a call to an old overloaded intrinsic. If it is, a new CallInst 
   /// is created that uses the correct Function and possibly casts the 
-  /// argument and result to an unsigned type.  The caller can use the 
-  /// returned Instruction to replace the existing one. Note that the
-  /// Instruction* returned could be a CallInst or a CastInst depending on
-  /// whether casting was necessary.
+  /// argument and result to an unsigned type.
   /// @param CI The CallInst to potentially auto-upgrade.
-  /// @returns An instrution to replace \p CI with.
   /// @brief Get replacement instruction for overloaded intrinsic function call.
-  Instruction* UpgradeIntrinsicCall(CallInst* CI, Function* newF = 0);
+  void UpgradeIntrinsicCall(CallInst* CI, Function* newF = 0);
 
   /// Upgrade both the function and all the calls made to it, if that function
   /// needs to be upgraded. This is like a combination of the above two
index 517cc3d5f129e531e2b34264df26823ed21152c3..775726d42ad841f35dbf7492ecbb244815a9c838 100644 (file)
@@ -148,9 +148,12 @@ namespace llvm {
     static inline bool classof(const MemIntrinsic *) { return true; }
     static inline bool classof(const IntrinsicInst *I) {
       switch (I->getIntrinsicID()) {
-      case Intrinsic::memcpy:
-      case Intrinsic::memmove:
-      case Intrinsic::memset:
+      case Intrinsic::memcpy_i32:
+      case Intrinsic::memcpy_i64:
+      case Intrinsic::memmove_i32:
+      case Intrinsic::memmove_i64:
+      case Intrinsic::memset_i32:
+      case Intrinsic::memset_i64:
         return true;
       default: return false;
       }
@@ -183,7 +186,8 @@ namespace llvm {
     // Methods for support type inquiry through isa, cast, and dyn_cast:
     static inline bool classof(const MemCpyInst *) { return true; }
     static inline bool classof(const IntrinsicInst *I) {
-      return I->getIntrinsicID() == Intrinsic::memcpy;
+      return I->getIntrinsicID() == Intrinsic::memcpy_i32 ||
+             I->getIntrinsicID() == Intrinsic::memcpy_i64;
     }
     static inline bool classof(const Value *V) {
       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
@@ -211,14 +215,15 @@ namespace llvm {
     // Methods for support type inquiry through isa, cast, and dyn_cast:
     static inline bool classof(const MemMoveInst *) { return true; }
     static inline bool classof(const IntrinsicInst *I) {
-      return I->getIntrinsicID() == Intrinsic::memmove;
+      return I->getIntrinsicID() == Intrinsic::memmove_i32 ||
+             I->getIntrinsicID() == Intrinsic::memmove_i64;
     }
     static inline bool classof(const Value *V) {
       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
     }
   };
 
-  /// MemSetInst - This class wraps the llvm.memcpy intrinsic.
+  /// MemSetInst - This class wraps the llvm.memset intrinsic.
   ///
   struct MemSetInst : public MemIntrinsic {
     /// get* - Return the arguments to the instruction.
@@ -234,7 +239,8 @@ namespace llvm {
     // Methods for support type inquiry through isa, cast, and dyn_cast:
     static inline bool classof(const MemSetInst *) { return true; }
     static inline bool classof(const IntrinsicInst *I) {
-      return I->getIntrinsicID() == Intrinsic::memset;
+      return I->getIntrinsicID() == Intrinsic::memset_i32 ||
+             I->getIntrinsicID() == Intrinsic::memset_i64;
     }
     static inline bool classof(const Value *V) {
       return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
index 37589c5153d975de24478aa706e639312ce85218..62c58f0ba753e33d4fa38a3a2d82c9a083b536c6 100644 (file)
@@ -59,13 +59,16 @@ namespace Intrinsic {
     dbg_declare,      // Declare a local object
 
     // Standard C library intrinsics.
-    memcpy,         // Copy non-overlapping memory blocks
-    memmove,        // Copy potentially overlapping memory blocks
-    memset,         // Fill memory with a byte value
-    isunordered_f32,// Return true if either float argument is a NaN
-    isunordered_f64,// Return true if either double argument is a NaN
-    sqrt_f32,       // Square root of float
-    sqrt_f64,       // Square root of double
+    memcpy_i32,      // Copy non-overlapping memory blocks.  i32 size.
+    memcpy_i64,      // Copy non-overlapping memory blocks.  i64 size.
+    memmove_i32,     // Copy potentially overlapping memory blocks.  i32 size.
+    memmove_i64,     // Copy potentially overlapping memory blocks.  i64 size.
+    memset_i32,      // Fill memory with a byte value.  i32 size.
+    memset_i64,      // Fill memory with a byte value.  i64 size.
+    isunordered_f32, // Return true if either float argument is a NaN
+    isunordered_f64, // Return true if either double argument is a NaN
+    sqrt_f32,        // Square root of float
+    sqrt_f64,        // Square root of double
 
     // Bit manipulation instrinsics.
     bswap_i16,      // Byteswap 16 bits
index 2b0ac90c6c2a5b67610bf1b84f896371f80741ee..10c9bb284704eb8249b2925345f2350bde43e757 100644 (file)
@@ -545,8 +545,10 @@ void GraphBuilder::visitCallSite(CallSite CS) {
         return;
       case Intrinsic::vaend:
         return;  // noop
-      case Intrinsic::memmove:
-      case Intrinsic::memcpy: {
+      case Intrinsic::memmove_i32:
+      case Intrinsic::memcpy_i32: 
+      case Intrinsic::memmove_i64:
+      case Intrinsic::memcpy_i64: {
         // Merge the first & second arguments, and mark the memory read and
         // modified.
         DSNodeHandle RetNH = getValueDest(**CS.arg_begin());
@@ -555,7 +557,8 @@ void GraphBuilder::visitCallSite(CallSite CS) {
           N->setModifiedMarker()->setReadMarker();
         return;
       }
-      case Intrinsic::memset:
+      case Intrinsic::memset_i32:
+      case Intrinsic::memset_i64:
         // Mark the memory modified.
         if (DSNode *N = getValueDest(**CS.arg_begin()).getNode())
           N->setModifiedMarker();
index c47a107cc33310403b15ff67ff9f4806f1a06989..a02d464981497cff61345b21ee5caf4ee0dfb5e1 100644 (file)
@@ -99,15 +99,18 @@ void DefaultIntrinsicLowering::AddPrototypes(Module &M) {
         EnsureFunctionExists(M, "abort", I->arg_end(), I->arg_end(),
                              Type::VoidTy);
         break;
-      case Intrinsic::memcpy:
+      case Intrinsic::memcpy_i32:
+      case Intrinsic::memcpy_i64:
         EnsureFunctionExists(M, "memcpy", I->arg_begin(), --I->arg_end(),
                              I->arg_begin()->getType());
         break;
-      case Intrinsic::memmove:
+      case Intrinsic::memmove_i32:
+      case Intrinsic::memmove_i64:
         EnsureFunctionExists(M, "memmove", I->arg_begin(), --I->arg_end(),
                              I->arg_begin()->getType());
         break;
-      case Intrinsic::memset:
+      case Intrinsic::memset_i32:
+      case Intrinsic::memset_i64:
         M.getOrInsertFunction("memset", PointerType::get(Type::SByteTy),
                               PointerType::get(Type::SByteTy),
                               Type::IntTy, (--(--I->arg_end()))->getType(),
@@ -405,7 +408,8 @@ void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
       CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
     break;    // Simply strip out debugging intrinsics
 
-  case Intrinsic::memcpy: {
+  case Intrinsic::memcpy_i32:
+  case Intrinsic::memcpy_i64: {
     // The memcpy intrinsic take an extra alignment argument that the memcpy
     // libc function does not.
     static Function *MemcpyFCache = 0;
@@ -413,7 +417,8 @@ void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
                     (*(CI->op_begin()+1))->getType(), MemcpyFCache);
     break;
   }
-  case Intrinsic::memmove: {
+  case Intrinsic::memmove_i32: 
+  case Intrinsic::memmove_i64: {
     // The memmove intrinsic take an extra alignment argument that the memmove
     // libc function does not.
     static Function *MemmoveFCache = 0;
@@ -421,7 +426,8 @@ void DefaultIntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
                     (*(CI->op_begin()+1))->getType(), MemmoveFCache);
     break;
   }
-  case Intrinsic::memset: {
+  case Intrinsic::memset_i32:
+  case Intrinsic::memset_i64: {
     // The memset intrinsic take an extra alignment argument that the memset
     // libc function does not.
     static Function *MemsetFCache = 0;
index cb69a2ae858999fa6e6663e5d53fefca05cddd60..10ee2d50915e3f49f34c9e32f64d346fc0080c61 100644 (file)
@@ -955,9 +955,18 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
   case Intrinsic::longjmp:
     return "_longjmp"+!TLI.usesUnderscoreSetJmpLongJmp();
     break;
-  case Intrinsic::memcpy:  visitMemIntrinsic(I, ISD::MEMCPY); return 0;
-  case Intrinsic::memset:  visitMemIntrinsic(I, ISD::MEMSET); return 0;
-  case Intrinsic::memmove: visitMemIntrinsic(I, ISD::MEMMOVE); return 0;
+  case Intrinsic::memcpy_i32:
+  case Intrinsic::memcpy_i64:
+    visitMemIntrinsic(I, ISD::MEMCPY);
+    return 0;
+  case Intrinsic::memset_i32:
+  case Intrinsic::memset_i64:
+    visitMemIntrinsic(I, ISD::MEMSET);
+    return 0;
+  case Intrinsic::memmove_i32:
+  case Intrinsic::memmove_i64:
+    visitMemIntrinsic(I, ISD::MEMMOVE);
+    return 0;
     
   case Intrinsic::readport:
   case Intrinsic::readio: {