[llvm-branch-commits] [llvm-gcc-branch] r119450 - in /llvm-gcc-4.2/branches/Apple/Morbo/gcc: config/i386/i386.c llvm-convert.cpp llvm-internal.h tree.h

Dale Johannesen dalej at apple.com
Tue Nov 16 18:07:51 PST 2010


Author: johannes
Date: Tue Nov 16 20:07:50 2010
New Revision: 119450

URL: http://llvm.org/viewvc/llvm-project?rev=119450&view=rev
Log:
--- Merging r112674 into '.':
U    gcc/llvm-convert.cpp
U    gcc/llvm-internal.h
--- Merging r119392 into '.':
U    gcc/tree.h
G    gcc/llvm-convert.cpp
U    gcc/config/i386/i386.c
Plus mods for MMX divergence from mainline.


Modified:
    llvm-gcc-4.2/branches/Apple/Morbo/gcc/config/i386/i386.c
    llvm-gcc-4.2/branches/Apple/Morbo/gcc/llvm-convert.cpp
    llvm-gcc-4.2/branches/Apple/Morbo/gcc/llvm-internal.h
    llvm-gcc-4.2/branches/Apple/Morbo/gcc/tree.h

Modified: llvm-gcc-4.2/branches/Apple/Morbo/gcc/config/i386/i386.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Morbo/gcc/config/i386/i386.c?rev=119450&r1=119449&r2=119450&view=diff
==============================================================================
--- llvm-gcc-4.2/branches/Apple/Morbo/gcc/config/i386/i386.c (original)
+++ llvm-gcc-4.2/branches/Apple/Morbo/gcc/config/i386/i386.c Tue Nov 16 20:07:50 2010
@@ -22161,7 +22161,7 @@
       decl = lookup_name (arg);
       if (decl == error_mark_node)
 	decl = 0;
-      if (decl == 0)
+      if (decl == 0 || !DECL_ASM_BLOCK_REGISTER (decl))
 	{
 	  tree type = iasm_type_for (arg);
 	  if (type)
@@ -22171,6 +22171,7 @@
 	      DECL_REGISTER (decl) = 1;
 	      C_DECL_REGISTER (decl) = 1;
 	      DECL_HARD_REGISTER (decl) = 1;
+              DECL_ASM_BLOCK_REGISTER (decl) = 1;
 	      set_user_assembler_name (decl, IDENTIFIER_POINTER (arg));
 	      decl = lang_hooks.decls.pushdecl (decl);
 	    }

Modified: llvm-gcc-4.2/branches/Apple/Morbo/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Morbo/gcc/llvm-convert.cpp?rev=119450&r1=119449&r2=119450&view=diff
==============================================================================
--- llvm-gcc-4.2/branches/Apple/Morbo/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/branches/Apple/Morbo/gcc/llvm-convert.cpp Tue Nov 16 20:07:50 2010
@@ -2410,14 +2410,18 @@
 //                           ... Expressions ...
 //===----------------------------------------------------------------------===//
 
-static bool canEmitRegisterVariable(tree exp) {
+static bool canEmitLocalRegisterVariable(tree exp) {
   // Only variables can be marked as 'register'.
   if (TREE_CODE(exp) != VAR_DECL || !DECL_REGISTER(exp))
     return false;
 
-  // We can emit inline assembler for access to global register variables.
+  // Global register variables are not accepted here.
   if (TREE_STATIC(exp) || DECL_EXTERNAL(exp) || TREE_PUBLIC(exp))
-    return true;
+    return false;
+
+  // Asm block register usage is not accepted here.
+  if (DECL_ASM_BLOCK_REGISTER (exp))
+    return false;
 
   // Emit inline asm if this is local variable with assembler name on it.
   if (DECL_ASSEMBLER_NAME_SET_P(exp))
@@ -2427,6 +2431,23 @@
   return false;
 }
 
+static bool canEmitGlobalRegisterVariable(tree exp) {
+  // Only variables can be marked as 'register'.
+  if (TREE_CODE(exp) != VAR_DECL || !DECL_REGISTER(exp))
+    return false;
+
+  // Treat register usage in asm blocks as global.
+  if (DECL_ASM_BLOCK_REGISTER (exp))
+    return true;
+
+  // Local register variables are not accepted here.
+  if (TREE_STATIC(exp) || DECL_EXTERNAL(exp) || TREE_PUBLIC(exp))
+    return true;
+
+  // Otherwise - it's normal automatic variable, or local register variable.
+  return false;
+}
+
 
 /// EmitLoadOfLValue - When an l-value expression is used in a context that
 /// requires an r-value, this method emits the lvalue computation, then loads
@@ -2444,10 +2465,10 @@
     DECL_GIMPLE_FORMAL_TEMP_P(exp) = 0;
     EmitAutomaticVariableDecl(exp);
     // Fall through.
-  } else if (canEmitRegisterVariable(exp)) {
-    // If this is a register variable, EmitLV can't handle it (there is no
-    // l-value of a register variable).  Emit an inline asm node that copies the
-    // value out of the specified register.
+  } else if (canEmitGlobalRegisterVariable(exp)) {
+    // If this is a global register variable, EmitLV can't handle it (there is
+    // no l-value of a global register variable).  Emit an inline asm node that
+    // copies the value out of the specified register.
     return EmitReadOfRegisterVariable(exp, DestLoc);
   }
 
@@ -2469,7 +2490,11 @@
       Value *Ptr = BitCastToType(LV.Ptr, Ty->getPointerTo());
       LoadInst *LI = Builder.CreateLoad(Ptr, isVolatile);
       LI->setAlignment(Alignment);
-      return LI;
+      if (canEmitLocalRegisterVariable(exp)) {
+        // For register variable, move the loaded variable into the right reg.
+        return EmitMoveOfRegVariableToRightReg(LI, exp);
+      } else
+        return LI;
     } else {
       EmitAggregateCopy(*DestLoc, MemRef(LV.Ptr, Alignment, isVolatile),
                         TREE_TYPE(exp));
@@ -3255,10 +3280,10 @@
     Builder.Insert(Cast);
     SET_DECL_LLVM(lhs, Cast);
     return Cast;
-  } else if (canEmitRegisterVariable(lhs)) {
-    // If this is a store to a register variable, EmitLV can't handle the dest
-    // (there is no l-value of a register variable).  Emit an inline asm node
-    // that copies the value into the specified register.
+  } else if (canEmitGlobalRegisterVariable(lhs)) {
+    // If this is a store to a global register variable, EmitLV can't handle the
+    // dest (there is no l-value of a global register variable).  Emit an inline
+    // asm node that copies the value into the specified register.
     Value *RHS = Emit(rhs, 0);
     RHS = CastToAnyType(RHS, RHSSigned, ConvertType(TREE_TYPE(lhs)), LHSSigned);
     EmitModifyOfRegisterVariable(lhs, RHS);
@@ -4187,8 +4212,8 @@
 #define LLVM_GET_REG_NAME(REG_NAME, REG_NUM) reg_names[REG_NUM]
 #endif
 
-/// Reads from register variables are handled by emitting an inline asm node
-/// that copies the value out of the specified register.
+ /// Reads from global register variables are handled by emitting an inline
+ /// asm node that copies the value out of the specified register.
 Value *TreeToLLVM::EmitReadOfRegisterVariable(tree decl,
                                               const MemRef *DestLoc) {
   const Type *Ty = ConvertType(TREE_TYPE(decl));
@@ -4213,8 +4238,43 @@
   return Call;
 }
 
-/// Stores to register variables are handled by emitting an inline asm node
-/// that copies the value into the specified register.
+/// Reads from register variables are handled by emitting an inline asm node
+/// that copies the value out of the specified register.
+Value *TreeToLLVM::EmitMoveOfRegVariableToRightReg(Instruction *I, tree var) {
+  // Create a 'call void asm sideeffect "", "{reg}"(Ty %RHS)'.
+  const Type *Ty = I->getType();
+
+  // If there was an error, return something bogus.
+  if (ValidateRegisterVariable(var)) {
+    if (Ty->isSingleValueType())
+      return UndefValue::get(Ty);
+    return 0;   // Just don't copy something into DestLoc.
+  }
+
+  std::vector<const Type*> ArgTys;
+  ArgTys.push_back(Ty);
+  FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), 
+                                        ArgTys, false);
+  const char *Name = extractRegisterName(var);
+  int RegNum = decode_reg_name(Name);
+  Name = LLVM_GET_REG_NAME(Name, RegNum);
+  InlineAsm *IA = InlineAsm::get(FTy, "", "{"+std::string(Name)+"}", 
+                                    true);
+  CallInst *Call = Builder.CreateCall(IA, I);
+  Call->setDoesNotThrow();
+  // Create another asm with the same reg, this time producing an output.
+  // Turn this into a 'tmp = call Ty asm "", "={reg}"()'.
+  FunctionType *FTy2 = FunctionType::get(Ty, std::vector<const Type*>(),
+                                        false);
+  InlineAsm *IA2 = InlineAsm::get(FTy2, "", "={"+std::string(Name)+"}",
+                                 true);
+  CallInst *Call2 = Builder.CreateCall(IA2);
+  Call2->setDoesNotThrow();
+  return Call2;
+}
+
+/// Stores to global register variables are handled by emitting an inline asm
+/// node that copies the value into the specified register.
 void TreeToLLVM::EmitModifyOfRegisterVariable(tree decl, Value *RHS) {
   // If there was an error, bail out.
   if (ValidateRegisterVariable(decl))
@@ -4222,7 +4282,8 @@
 
   // Turn this into a 'call void asm sideeffect "", "{reg}"(Ty %RHS)'.
   std::vector<const Type*> ArgTys;
-  ArgTys.push_back(ConvertType(TREE_TYPE(decl)));
+  const Type* Ty = ConvertType(TREE_TYPE(decl));
+  ArgTys.push_back(Ty);
   FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), ArgTys, false);
 
   const char *Name = extractRegisterName(decl);

Modified: llvm-gcc-4.2/branches/Apple/Morbo/gcc/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Morbo/gcc/llvm-internal.h?rev=119450&r1=119449&r2=119450&view=diff
==============================================================================
--- llvm-gcc-4.2/branches/Apple/Morbo/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/branches/Apple/Morbo/gcc/llvm-internal.h Tue Nov 16 20:07:50 2010
@@ -526,6 +526,7 @@
   Value *EmitASM_EXPR(tree_node *exp);
   Value *EmitReadOfRegisterVariable(tree_node *vardecl, const MemRef *DestLoc);
   void EmitModifyOfRegisterVariable(tree_node *vardecl, Value *RHS);
+  Value *EmitMoveOfRegVariableToRightReg(Instruction *I, tree_node *decl);
 
   // Helpers for Builtin Function Expansion.
   void EmitMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device);

Modified: llvm-gcc-4.2/branches/Apple/Morbo/gcc/tree.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/branches/Apple/Morbo/gcc/tree.h?rev=119450&r1=119449&r2=119450&view=diff
==============================================================================
--- llvm-gcc-4.2/branches/Apple/Morbo/gcc/tree.h (original)
+++ llvm-gcc-4.2/branches/Apple/Morbo/gcc/tree.h Tue Nov 16 20:07:50 2010
@@ -2623,6 +2623,8 @@
      In VAR_DECL and PARM_DECL, this is DECL_REGISTER.  */
   unsigned decl_flag_0 : 1;
   /* In FIELD_DECL, this is DECL_PACKED.  */
+  /* LLVM LOCAL */
+  /* In VAR_DECL, this is DECL_ASM_BLOCK_REGISTER. */
   unsigned decl_flag_1 : 1;
   /* In FIELD_DECL, this is DECL_BIT_FIELD
      In VAR_DECL and FUNCTION_DECL, this is DECL_EXTERNAL.
@@ -2703,6 +2705,9 @@
 /* In VAR_DECL and PARM_DECL nodes, nonzero means declared `register'.  */
 #define DECL_REGISTER(NODE) (DECL_WRTL_CHECK (NODE)->decl_common.decl_flag_0)
 
+/* In VAR_DECL, nonzero means a register used by asm block code. */
+#define DECL_ASM_BLOCK_REGISTER(NODE) (DECL_WRTL_CHECK (NODE)->decl_common.decl_flag_1)
+
 struct tree_decl_with_rtl GTY(())
 {
   struct tree_decl_common common;





More information about the llvm-branch-commits mailing list