aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
diff options
context:
space:
mode:
authorMatt Beaumont-Gay <matthewbg@google.com>2012-12-14 17:55:15 +0000
committerMatt Beaumont-Gay <matthewbg@google.com>2012-12-14 17:55:15 +0000
commit6aed25d93d1cfcde5809a73ffa7dc1b0d6396f66 (patch)
tree57e2fdf1caf960d8d878e0289f32af6759832b49 /lib/Target/NVPTX/NVPTXAsmPrinter.cpp
parent7139cfb19b1cc28dfd5e274c07ec68835bc6d6d6 (diff)
parent1ad9253c9d34ccbce3e7e4ea5d87c266cbf93410 (diff)
Updating branches/google/stable to r169803
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/google/stable@170212 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/NVPTX/NVPTXAsmPrinter.cpp')
-rw-r--r--lib/Target/NVPTX/NVPTXAsmPrinter.cpp118
1 files changed, 93 insertions, 25 deletions
diff --git a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
index d3dfb35e26..af07576d59 100644
--- a/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
+++ b/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
@@ -13,36 +13,36 @@
//===----------------------------------------------------------------------===//
#include "NVPTXAsmPrinter.h"
+#include "MCTargetDesc/NVPTXMCAsmInfo.h"
#include "NVPTX.h"
#include "NVPTXInstrInfo.h"
-#include "NVPTXTargetMachine.h"
+#include "NVPTXNumRegisters.h"
#include "NVPTXRegisterInfo.h"
+#include "NVPTXTargetMachine.h"
#include "NVPTXUtilities.h"
-#include "MCTargetDesc/NVPTXMCAsmInfo.h"
-#include "NVPTXNumRegisters.h"
+#include "cl_common_defines.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/DebugInfo.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Module.h"
+#include "llvm/Analysis/ConstantFolding.h"
+#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/Analysis.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/DebugInfo.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Target/Mangler.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
-#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Module.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Support/TimeValue.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Support/Path.h"
-#include "llvm/Assembly/Writer.h"
-#include "cl_common_defines.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TimeValue.h"
+#include "llvm/Target/Mangler.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
#include <sstream>
using namespace llvm;
@@ -68,7 +68,54 @@ static cl::opt<bool, true>InterleaveSrc("nvptx-emit-src",
cl::location(llvm::InterleaveSrcInPtx));
+namespace {
+/// DiscoverDependentGlobals - Return a set of GlobalVariables on which \p V
+/// depends.
+void DiscoverDependentGlobals(Value *V,
+ DenseSet<GlobalVariable*> &Globals) {
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
+ Globals.insert(GV);
+ else {
+ if (User *U = dyn_cast<User>(V)) {
+ for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i) {
+ DiscoverDependentGlobals(U->getOperand(i), Globals);
+ }
+ }
+ }
+}
+/// VisitGlobalVariableForEmission - Add \p GV to the list of GlobalVariable
+/// instances to be emitted, but only after any dependents have been added
+/// first.
+void VisitGlobalVariableForEmission(GlobalVariable *GV,
+ SmallVectorImpl<GlobalVariable*> &Order,
+ DenseSet<GlobalVariable*> &Visited,
+ DenseSet<GlobalVariable*> &Visiting) {
+ // Have we already visited this one?
+ if (Visited.count(GV)) return;
+
+ // Do we have a circular dependency?
+ if (Visiting.count(GV))
+ report_fatal_error("Circular dependency found in global variable set");
+
+ // Start visiting this global
+ Visiting.insert(GV);
+
+ // Make sure we visit all dependents first
+ DenseSet<GlobalVariable*> Others;
+ for (unsigned i = 0, e = GV->getNumOperands(); i != e; ++i)
+ DiscoverDependentGlobals(GV->getOperand(i), Others);
+
+ for (DenseSet<GlobalVariable*>::iterator I = Others.begin(),
+ E = Others.end(); I != E; ++I)
+ VisitGlobalVariableForEmission(*I, Order, Visited, Visiting);
+
+ // Now we can visit ourself
+ Order.push_back(GV);
+ Visited.insert(GV);
+ Visiting.erase(GV);
+}
+}
// @TODO: This is a copy from AsmPrinter.cpp. The function is static, so we
// cannot just link to the existing version.
@@ -631,7 +678,7 @@ void NVPTXAsmPrinter::printLdStCode(const MachineInstr *MI, int opNum,
O << ".global";
break;
default:
- assert("wrong value");
+ llvm_unreachable("Wrong Address Space");
}
}
else if (!strcmp(Modifier, "sign")) {
@@ -649,10 +696,10 @@ void NVPTXAsmPrinter::printLdStCode(const MachineInstr *MI, int opNum,
O << ".v4";
}
else
- assert("unknown modifier");
+ llvm_unreachable("Unknown Modifier");
}
else
- assert("unknown modifier");
+ llvm_unreachable("Empty Modifier");
}
void NVPTXAsmPrinter::emitDeclaration (const Function *F, raw_ostream &O) {
@@ -893,10 +940,27 @@ bool NVPTXAsmPrinter::doInitialization (Module &M) {
emitDeclarations(M, OS2);
- // Print out module-level global variables here.
+ // As ptxas does not support forward references of globals, we need to first
+ // sort the list of module-level globals in def-use order. We visit each
+ // global variable in order, and ensure that we emit it *after* its dependent
+ // globals. We use a little extra memory maintaining both a set and a list to
+ // have fast searches while maintaining a strict ordering.
+ SmallVector<GlobalVariable*,8> Globals;
+ DenseSet<GlobalVariable*> GVVisited;
+ DenseSet<GlobalVariable*> GVVisiting;
+
+ // Visit each global variable, in order
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
- I != E; ++I)
- printModuleLevelGV(I, OS2);
+ I != E; ++I)
+ VisitGlobalVariableForEmission(I, Globals, GVVisited, GVVisiting);
+
+ assert(GVVisited.size() == M.getGlobalList().size() &&
+ "Missed a global variable");
+ assert(GVVisiting.size() == 0 && "Did not fully process a global variable");
+
+ // Print out module-level global variables in proper order
+ for (unsigned i = 0, e = Globals.size(); i != e; ++i)
+ printModuleLevelGV(Globals[i], OS2);
OS2 << '\n';
@@ -910,7 +974,8 @@ void NVPTXAsmPrinter::emitHeader (Module &M, raw_ostream &O) {
O << "//\n";
O << "\n";
- O << ".version 3.0\n";
+ unsigned PTXVersion = nvptxSubtarget.getPTXVersion();
+ O << ".version " << (PTXVersion / 10) << "." << (PTXVersion % 10) << "\n";
O << ".target ";
O << nvptxSubtarget.getTargetName();
@@ -1422,7 +1487,7 @@ void NVPTXAsmPrinter::printParamName(int paramIndex, raw_ostream &O) {
void NVPTXAsmPrinter::emitFunctionParamList(const Function *F,
raw_ostream &O) {
const DataLayout *TD = TM.getDataLayout();
- const AttrListPtr &PAL = F->getAttributes();
+ const AttributeSet &PAL = F->getAttributes();
const TargetLowering *TLI = TM.getTargetLowering();
Function::const_arg_iterator I, E;
unsigned paramIndex = 0;
@@ -1525,6 +1590,9 @@ void NVPTXAsmPrinter::emitFunctionParamList(const Function *F,
// <a> = PAL.getparamalignment
// size = typeallocsize of element type
unsigned align = PAL.getParamAlignment(paramIndex+1);
+ if (align == 0)
+ align = TD->getABITypeAlignment(ETy);
+
unsigned sz = TD->getTypeAllocSize(ETy);
O << "\t.param .align " << align
<< " .b8 ";