[llvm-commits] [gcc-plugin] r76562 - /gcc-plugin/trunk/llvm-convert.cpp
Duncan Sands
baldrick at free.fr
Tue Jul 21 03:34:48 PDT 2009
Author: baldrick
Date: Tue Jul 21 05:34:44 2009
New Revision: 76562
URL: http://llvm.org/viewvc/llvm-project?rev=76562&view=rev
Log:
Update to llvm-gcc revision 76542.
Modified:
gcc-plugin/trunk/llvm-convert.cpp
Modified: gcc-plugin/trunk/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/gcc-plugin/trunk/llvm-convert.cpp?rev=76562&r1=76561&r2=76562&view=diff
==============================================================================
--- gcc-plugin/trunk/llvm-convert.cpp (original)
+++ gcc-plugin/trunk/llvm-convert.cpp Tue Jul 21 05:34:44 2009
@@ -38,6 +38,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/DenseMap.h"
@@ -530,10 +531,14 @@
else if (flag_stack_protect == 2)
Fn->addFnAttr(Attribute::StackProtectReq);
+ // Handle naked attribute
+ if (lookup_attribute ("naked", DECL_ATTRIBUTES (FnDecl)))
+ Fn->addFnAttr(Attribute::Naked);
+
// Handle annotate attributes
if (DECL_ATTRIBUTES(FnDecl))
AddAnnotateAttrsToGlobal(Fn, FnDecl);
-
+
// Mark the function "nounwind" if not doing exception handling.
if (!flag_exceptions)
Fn->setDoesNotThrow();
@@ -2177,6 +2182,24 @@
// ... Expressions ...
//===----------------------------------------------------------------------===//
+static bool canEmitRegisterVariable(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.
+ if (TREE_STATIC(exp) || DECL_EXTERNAL(exp) || TREE_PUBLIC(exp))
+ return true;
+
+ // Emit inline asm if this is local variable with assembler name on it.
+ if (DECL_ASSEMBLER_NAME_SET_P(exp))
+ return true;
+
+ // Otherwise - it's normal automatic 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
/// the result.
@@ -2194,8 +2217,7 @@
//FIXME DECL_GIMPLE_FORMAL_TEMP_P(exp) = 0;
EmitAutomaticVariableDecl(exp);
// Fall through.
- } else if (TREE_CODE(exp) == VAR_DECL && DECL_REGISTER(exp) &&
- TREE_STATIC(exp)) {
+ } 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.
@@ -2887,8 +2909,7 @@
Builder.Insert(Cast);
SET_DECL_LLVM(lhs, Cast);
return Cast;
- } else if (TREE_CODE(lhs) == VAR_DECL && DECL_REGISTER(lhs) &&
- TREE_STATIC(lhs)) {
+ } 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.
@@ -3811,19 +3832,20 @@
Value *TreeToLLVM::EmitReadOfRegisterVariable(tree decl,
const MemRef *DestLoc) {
const Type *Ty = ConvertType(TREE_TYPE(decl));
-
+
// If there was an error, return something bogus.
if (ValidateRegisterVariable(decl)) {
if (Ty->isSingleValueType())
return Context.getUndef(Ty);
return 0; // Just don't copy something into DestLoc.
}
-
+
// Turn this into a 'tmp = call Ty asm "", "={reg}"()'.
FunctionType *FTy =
Context.getFunctionType(Ty, std::vector<const Type*>(),false);
-
- const char *Name = extractRegisterName(decl);
+
+ const char *Name = reg_names[decode_reg_name(extractRegisterName(decl))];
+
InlineAsm *IA = InlineAsm::get(FTy, "", "={"+std::string(Name)+"}", false);
CallInst *Call = Builder.CreateCall(IA);
Call->setDoesNotThrow();
@@ -3836,13 +3858,14 @@
// If there was an error, bail out.
if (ValidateRegisterVariable(decl))
return;
-
+
// Turn this into a 'call void asm sideeffect "", "{reg}"(Ty %RHS)'.
std::vector<const Type*> ArgTys;
ArgTys.push_back(ConvertType(TREE_TYPE(decl)));
FunctionType *FTy = Context.getFunctionType(Type::VoidTy, ArgTys, false);
-
- const char *Name = extractRegisterName(decl);
+
+ const char *Name = reg_names[decode_reg_name(extractRegisterName(decl))];
+
InlineAsm *IA = InlineAsm::get(FTy, "", "{"+std::string(Name)+"}", true);
CallInst *Call = Builder.CreateCall(IA, RHS);
Call->setDoesNotThrow();
@@ -4212,6 +4235,22 @@
free((char *)ReplacementStrings[i]);
}
+// When extracting a register name from a DECL_HARD_REGISTER variable,
+// we normally want to look up RegNum in reg_names. This works on most
+// targets, where ADDITIONAL_REGISTER_NAMES are true synonyms. It does not
+// work on x86, where ADDITIONAL_REGISTER_NAMES are overlapping subregisters;
+// in particular AH and AL can't be distinguished if we go through reg_names.
+static const char* getConstraintRegNameFromGccTables(const char *RegName,
+ unsigned int RegNum) {
+#ifdef LLVM_DO_NOT_USE_REG_NAMES
+ if (*RegName == '%')
+ RegName++;
+ return RegName;
+#else
+ return reg_names[RegNum];
+#endif
+}
+
Value *TreeToLLVM::EmitASM_EXPR(tree exp) {
unsigned NumInputs = list_length(ASM_INPUTS(exp));
unsigned NumOutputs = list_length(ASM_OUTPUTS(exp));
@@ -4330,9 +4369,7 @@
const char* RegName = extractRegisterName(Operand);
int RegNum = decode_reg_name(RegName);
if (RegNum >= 0) {
- // Constraints don't have the leading %, the variable names do
- if (*RegName == '%')
- RegName++;
+ RegName = getConstraintRegNameFromGccTables(RegName, RegNum);
unsigned RegNameLen = strlen(RegName);
char *NewConstraint = (char*)alloca(RegNameLen+4);
NewConstraint[0] = '=';
@@ -4484,8 +4521,7 @@
const char *RegName = extractRegisterName(Val);
int RegNum = decode_reg_name(RegName);
if (RegNum >= 0) {
- if (*RegName == '%') // Variables have leading %.
- RegName++; // Constraints don't.
+ RegName = getConstraintRegNameFromGccTables(RegName, RegNum);
ConstraintStr += '{';
ConstraintStr += RegName;
ConstraintStr += '}';
@@ -4522,8 +4558,7 @@
ConstraintStr += ",~{memory}";
break;
default: // Normal register name.
- if (*RegName == '%')
- RegName++;
+ RegName = getConstraintRegNameFromGccTables(RegName, RegCode);
ConstraintStr += ",~{";
ConstraintStr += RegName;
ConstraintStr += "}";
@@ -4576,8 +4611,8 @@
// Give the backend a chance to upgrade the inline asm to LLVM code. This
// handles some common cases that LLVM has intrinsics for, e.g. x86 bswap ->
// llvm.bswap.
- if (const TargetAsmInfo *TAI = TheTarget->getTargetAsmInfo())
- TAI->ExpandInlineAsm(CV);
+ if (const TargetLowering *TLI = TheTarget->getTargetLowering())
+ TLI->ExpandInlineAsm(CV);
if (NumChoices>1)
FreeConstTupleStrings(ReplacementStrings, NumInputs+NumOutputs);
More information about the llvm-commits
mailing list