[cfe-commits] r97547 - in /cfe/trunk: include/clang/Basic/Builtins.def lib/CodeGen/CGBuiltin.cpp lib/CodeGen/TargetInfo.h

John McCall rjmccall at apple.com
Mon Mar 1 19:50:12 PST 2010


Author: rjmccall
Date: Mon Mar  1 21:50:12 2010
New Revision: 97547

URL: http://llvm.org/viewvc/llvm-project?rev=97547&view=rev
Log:
Inspired by seeing "MIPS" go by in the commits, I've gone ahead and
implemented a (codegen) target hook for __builtin_extend_pointer.
I'm also making it return a uint64_t instead of an unsigned word;  this
comports with typical usage (i.e. the one use I know of).

I don't know if any of the existing targets requires this hook to be
set (other than x86 and x86_64, which I know do not).


Modified:
    cfe/trunk/include/clang/Basic/Builtins.def
    cfe/trunk/lib/CodeGen/CGBuiltin.cpp
    cfe/trunk/lib/CodeGen/TargetInfo.h

Modified: cfe/trunk/include/clang/Basic/Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Builtins.def?rev=97547&r1=97546&r2=97547&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Builtins.def (original)
+++ cfe/trunk/include/clang/Basic/Builtins.def Mon Mar  1 21:50:12 2010
@@ -317,7 +317,7 @@
 BUILTIN(__builtin_dwarf_cfa, "v*", "n")
 BUILTIN(__builtin_init_dwarf_reg_size_table, "vv*", "n")
 BUILTIN(__builtin_dwarf_sp_column, "Ui", "n")
-BUILTIN(__builtin_extend_pointer, "zv*", "n") // Really _Unwind_Ptr -> _Unwind_Word
+BUILTIN(__builtin_extend_pointer, "ULLiv*", "n") // _Unwind_Word == uint64_t
 
 // GCC Object size checking builtins
 BUILTIN(__builtin_object_size, "zv*i", "n")

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=97547&r1=97546&r2=97547&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Mon Mar  1 21:50:12 2010
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "TargetInfo.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "clang/Basic/TargetInfo.h"
@@ -19,6 +20,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/Basic/TargetBuiltins.h"
 #include "llvm/Intrinsics.h"
+#include "llvm/Target/TargetData.h"
 using namespace clang;
 using namespace CodeGen;
 using namespace llvm;
@@ -367,19 +369,32 @@
   }
   case Builtin::BI__builtin_extend_pointer: {
     // Extends a pointer to the size of an _Unwind_Word, which is
-    // generally a uint64_t.  Generally this gets poked directly into
-    // a register (or a "register" depending on platform) and then
-    // called, so if the pointer is shorter than a word we need to
-    // zext / sext based on the platform's expectations for pointers
-    // in registers.
+    // uint64_t on all platforms.  Generally this gets poked into a
+    // register and eventually used as an address, so if the
+    // addressing registers are wider than pointers and the platform
+    // doesn't implicitly ignore high-order bits when doing
+    // addressing, we need to make sure we zext / sext based on
+    // the platform's expectations.
     //
     // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html
-    //
-    // FIXME: ptrtoint always zexts; use a target hook if we start
-    // supporting targets where this matters.
+
+    LLVMContext &C = CGM.getLLVMContext();
+
+    // Cast the pointer to intptr_t.
     Value *Ptr = EmitScalarExpr(E->getArg(0));
-    const llvm::Type *Ty = CGM.getTypes().ConvertType(E->getType());
-    return RValue::get(Builder.CreatePtrToInt(Ptr, Ty));
+    const llvm::IntegerType *IntPtrTy = CGM.getTargetData().getIntPtrType(C);
+    Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast");
+
+    // If that's 64 bits, we're done.
+    if (IntPtrTy->getBitWidth() == 64)
+      return RValue::get(Result);
+
+    // Otherwise, ask the codegen data what to do.
+    const llvm::IntegerType *Int64Ty = llvm::IntegerType::get(C, 64);
+    if (CGM.getTargetCodeGenInfo().extendPointerWithSExt())
+      return RValue::get(Builder.CreateSExt(Result, Int64Ty, "extend.sext"));
+    else
+      return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext"));
   }
 #if 0
   // FIXME: Finish/enable when LLVM backend support stabilizes

Modified: cfe/trunk/lib/CodeGen/TargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.h?rev=97547&r1=97546&r2=97547&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.h (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.h Mon Mar  1 21:50:12 2010
@@ -44,6 +44,15 @@
     /// target-specific attributes for the given global.
     virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
                                      CodeGen::CodeGenModule &M) const { }
+
+    /// Controls whether __builtin_extend_pointer should sign-extend
+    /// pointers to uint64_t or zero-extend them (the default).  Has
+    /// no effect for targets:
+    ///   - that have 64-bit pointers, or
+    ///   - that cannot address through registers larger than pointers, or
+    ///   - that implicitly ignore/truncate the top bits when addressing
+    ///     through such registers.
+    virtual bool extendPointerWithSExt() const { return false; }
   };
 }
 





More information about the cfe-commits mailing list