aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNate Begeman <natebegeman@mac.com>2005-07-12 01:41:54 +0000
committerNate Begeman <natebegeman@mac.com>2005-07-12 01:41:54 +0000
commitfb5792f416089d8d8d0c6ee62c1f41a55d2cf75d (patch)
treee2b2a65b1d1e7f426d6f3035bca964ce25c0d79d
parent73213f6c07afc1479f8d7bf53ea99adf7fd60b78 (diff)
Implement Subtarget support
Implement the X86 Subtarget. This consolidates the checks for target triple, and setting options based on target triple into one place. This allows us to convert the asm printer and isel over from being littered with "forDarwin", "forCygwin", etc. into just having the appropriate flags for each subtarget feature controlling the code for that feature. This patch also implements indirect external and weak references in the X86 pattern isel, for darwin. Next up is to convert over the asm printers to use this new interface. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22389 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Target/TargetMachine.h8
-rw-r--r--include/llvm/Target/TargetSubtarget.h41
-rw-r--r--lib/Target/TargetSubtarget.cpp22
-rw-r--r--lib/Target/X86/X86ISelPattern.cpp31
-rw-r--r--lib/Target/X86/X86Subtarget.cpp59
-rw-r--r--lib/Target/X86/X86Subtarget.h55
-rw-r--r--lib/Target/X86/X86TargetMachine.cpp4
-rw-r--r--lib/Target/X86/X86TargetMachine.h3
8 files changed, 219 insertions, 4 deletions
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 6e3fe35ab1..efeb61d499 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -19,6 +19,7 @@
namespace llvm {
+class TargetSubtarget;
class TargetInstrInfo;
class TargetInstrDescriptor;
class TargetJITInfo;
@@ -97,6 +98,13 @@ public:
virtual const TargetFrameInfo *getFrameInfo() const { return 0; }
const TargetData &getTargetData() const { return DataLayout; }
+ virtual const TargetSubtarget *getSubtargetImpl() const { return 0; }
+ template<typename STC> STC *getSubtarget() const {
+ assert(getSubtargetImpl() && dynamic_cast<STC*>(getSubtargetImpl()) &&
+ "Not the right kind of subtarget!");
+ return (STC*)getSubtargetImpl();
+ }
+
/// getRegisterInfo - If register information is available, return it. If
/// not, return null. This is kept separate from RegInfo until RegInfo has
/// details of graph coloring register allocation removed from it.
diff --git a/include/llvm/Target/TargetSubtarget.h b/include/llvm/Target/TargetSubtarget.h
new file mode 100644
index 0000000000..e99afe2468
--- /dev/null
+++ b/include/llvm/Target/TargetSubtarget.h
@@ -0,0 +1,41 @@
+//==-- llvm/Target/TargetSubtarget.h - Target Information --------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Nate Begeman and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the subtarget options of a Target machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETSUBTARGET_H
+#define LLVM_TARGET_TARGETSUBTARGET_H
+
+namespace llvm {
+
+class Module;
+
+//===----------------------------------------------------------------------===//
+///
+/// TargetSubtarget - Generic base class for all target subtargets. All
+/// Target-specific options that control code generation and printing should
+/// be exposed through a TargetSubtarget-derived class.
+///
+class TargetSubtarget {
+ TargetSubtarget(const TargetSubtarget&); // DO NOT IMPLEMENT
+ void operator=(const TargetSubtarget&); // DO NOT IMPLEMENT
+protected: // Can only create subclasses...
+ /// This constructor initializes the data members to match that
+ /// of the specified module.
+ ///
+ TargetSubtarget(const Module &M);
+public:
+ virtual ~TargetSubtarget();
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/lib/Target/TargetSubtarget.cpp b/lib/Target/TargetSubtarget.cpp
new file mode 100644
index 0000000000..ebb1308475
--- /dev/null
+++ b/lib/Target/TargetSubtarget.cpp
@@ -0,0 +1,22 @@
+//===-- TargetSubtarget.cpp - General Target Information -------------------==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Nate Begeman and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the general parts of a Subtarget.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Target/TargetSubtarget.h"
+using namespace llvm;
+
+//---------------------------------------------------------------------------
+// TargetSubtarget Class
+//
+TargetSubtarget::TargetSubtarget(const Module &M) {}
+
+TargetSubtarget::~TargetSubtarget() {}
diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp
index 66e6f71bff..6bd8e27607 100644
--- a/lib/Target/X86/X86ISelPattern.cpp
+++ b/lib/Target/X86/X86ISelPattern.cpp
@@ -14,6 +14,7 @@
#include "X86.h"
#include "X86InstrBuilder.h"
#include "X86RegisterInfo.h"
+#include "X86Subtarget.h"
#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
@@ -26,6 +27,7 @@
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLowering.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/MathExtras.h"
@@ -996,8 +998,13 @@ namespace {
/// TheDAG - The DAG being selected during Select* operations.
SelectionDAG *TheDAG;
+
+ /// Subtarget - Keep a pointer to the X86Subtarget around so that we can
+ /// make the right decision when generating code for different targets.
+ const X86Subtarget *Subtarget;
public:
ISel(TargetMachine &TM) : SelectionDAGISel(X86Lowering), X86Lowering(TM) {
+ Subtarget = TM.getSubtarget<const X86Subtarget>();
}
virtual const char *getPassName() const {
@@ -1314,8 +1321,18 @@ bool ISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM) {
break;
case ISD::GlobalAddress:
if (AM.GV == 0) {
- AM.GV = cast<GlobalAddressSDNode>(N)->getGlobal();
- return false;
+ GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
+ // For Darwin, external and weak symbols are indirect, so we want to load
+ // the value at address GV, not the value of GV itself. This means that
+ // the GlobalAddress must be in the base or index register of the address,
+ // not the GV offset field.
+ if (Subtarget->getIndirectExternAndWeakGlobals() &&
+ (GV->hasWeakLinkage() || GV->isExternal())) {
+ break;
+ } else {
+ AM.GV = GV;
+ return false;
+ }
}
break;
case ISD::Constant:
@@ -2236,7 +2253,15 @@ unsigned ISel::SelectExpr(SDOperand N) {
return Result;
case ISD::GlobalAddress: {
GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
- BuildMI(BB, X86::MOV32ri, 1, Result).addGlobalAddress(GV);
+ // For Darwin, external and weak symbols are indirect, so we want to load
+ // the value at address GV, not the value of GV itself.
+ if (Subtarget->getIndirectExternAndWeakGlobals() &&
+ (GV->hasWeakLinkage() || GV->isExternal())) {
+ BuildMI(BB, X86::MOV32rm, 4, Result).addReg(0).addZImm(1).addReg(0)
+ .addGlobalAddress(GV, false, 0);
+ } else {
+ BuildMI(BB, X86::MOV32ri, 1, Result).addGlobalAddress(GV);
+ }
return Result;
}
case ISD::ExternalSymbol: {
diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp
new file mode 100644
index 0000000000..e50d2d6d87
--- /dev/null
+++ b/lib/Target/X86/X86Subtarget.cpp
@@ -0,0 +1,59 @@
+//===- X86Subtarget.cpp - X86 Instruction Information -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Nate Begeman and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the X86 specific subclass of TargetSubtarget.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86Subtarget.h"
+#include "llvm/Module.h"
+using namespace llvm;
+
+X86Subtarget::X86Subtarget(const Module &M)
+ : TargetSubtarget(M), stackAlignment(8),
+ indirectExternAndWeakGlobals(false), asmDarwinLinkerStubs(false),
+ asmLeadingUnderscore(false), asmAlignmentIsInBytes(false),
+ asmPrintDotLocalConstants(false), asmPrintDotLCommConstants(false),
+ asmPrintConstantAlignment(false) {
+ // Declare a boolean for each platform
+ bool forCygwin = false;
+ bool forDarwin = false;
+ bool forWindows = false;
+
+ // Set the boolean corresponding to the current target triple, or the default
+ // if one cannot be determined, to true.
+ const std::string& TT = M.getTargetTriple();
+ if (TT.length() > 5) {
+ forCygwin = TT.find("cygwin") != std::string::npos ||
+ TT.find("mingw") != std::string::npos;
+ forDarwin = TT.find("darwin") != std::string::npos;
+ forWindows = TT.find("win32") != std::string::npos;
+ } else if (TT.empty()) {
+#if defined(__CYGWIN__) || defined(__MINGW32__)
+ forCygwin = true;
+#elif defined(__APPLE__)
+ forDarwin = true;
+#elif defined(_WIN32)
+ forWindws = true;
+#endif
+ }
+
+ if (forCygwin) {
+ asmLeadingUnderscore = true;
+ }
+ if (forDarwin) {
+ stackAlignment = 16;
+ indirectExternAndWeakGlobals = true;
+ asmDarwinLinkerStubs = true;
+ asmLeadingUnderscore = true;
+ asmPrintDotLCommConstants = true;
+ }
+ if (forWindows) {
+ }
+}
diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h
new file mode 100644
index 0000000000..96a1bb2cc0
--- /dev/null
+++ b/lib/Target/X86/X86Subtarget.h
@@ -0,0 +1,55 @@
+//=====-- X86Subtarget.h - Define TargetMachine for the X86 ---*- C++ -*--====//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Nate Begeman and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the X86 specific subclass of TargetSubtarget.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef X86SUBTARGET_H
+#define X86SUBTARGET_H
+
+#include "llvm/Target/TargetSubtarget.h"
+
+namespace llvm {
+class Module;
+
+class X86Subtarget : public TargetSubtarget {
+protected:
+ /// Used by the target machine to set up the target frame info
+ unsigned stackAlignment;
+
+ /// Used by instruction selector
+ bool indirectExternAndWeakGlobals;
+
+ /// Used by the asm printer
+ bool asmDarwinLinkerStubs;
+ bool asmLeadingUnderscore;
+ bool asmAlignmentIsInBytes;
+ bool asmPrintDotLocalConstants;
+ bool asmPrintDotLCommConstants;
+ bool asmPrintConstantAlignment;
+public:
+ /// This constructor initializes the data members to match that
+ /// of the specified module.
+ ///
+ X86Subtarget(const Module &M);
+
+ /// Returns the preferred stack alignment for the current target triple, or
+ /// the default if no target triple is set.
+ unsigned getStackAlignment() const { return stackAlignment; }
+
+ /// Returns true if the instruction selector should treat global values
+ /// referencing external or weak symbols as indirect rather than direct
+ /// references.
+ bool getIndirectExternAndWeakGlobals() const {
+ return indirectExternAndWeakGlobals; }
+};
+} // End llvm namespace
+
+#endif
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index a0537f529c..f4d5ba40ec 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -92,7 +92,9 @@ unsigned X86TargetMachine::getModuleMatchQuality(const Module &M) {
///
X86TargetMachine::X86TargetMachine(const Module &M, IntrinsicLowering *IL)
: TargetMachine("X86", IL, true, 4, 4, 4, 4, 4),
- FrameInfo(TargetFrameInfo::StackGrowsDown, 8, -4),
+ Subtarget(M),
+ FrameInfo(TargetFrameInfo::StackGrowsDown,
+ Subtarget.getStackAlignment(), -4),
JITInfo(*this) {
// Scalar SSE FP requires at least SSE2
X86ScalarSSE &= X86Vector >= SSE2;
diff --git a/lib/Target/X86/X86TargetMachine.h b/lib/Target/X86/X86TargetMachine.h
index 70b111c38b..955f855602 100644
--- a/lib/Target/X86/X86TargetMachine.h
+++ b/lib/Target/X86/X86TargetMachine.h
@@ -19,12 +19,14 @@
#include "llvm/PassManager.h"
#include "X86InstrInfo.h"
#include "X86JITInfo.h"
+#include "X86Subtarget.h"
namespace llvm {
class IntrinsicLowering;
class X86TargetMachine : public TargetMachine {
X86InstrInfo InstrInfo;
+ X86Subtarget Subtarget;
TargetFrameInfo FrameInfo;
X86JITInfo JITInfo;
public:
@@ -33,6 +35,7 @@ public:
virtual const X86InstrInfo *getInstrInfo() const { return &InstrInfo; }
virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; }
virtual TargetJITInfo *getJITInfo() { return &JITInfo; }
+ virtual const TargetSubtarget *getSubtargetImpl() const{ return &Subtarget; }
virtual const MRegisterInfo *getRegisterInfo() const {
return &InstrInfo.getRegisterInfo();
}