aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp55
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp12
-rw-r--r--lib/CodeGen/BranchFolding.cpp16
-rw-r--r--lib/CodeGen/CallingConvLower.cpp1
-rw-r--r--lib/CodeGen/MachineBasicBlock.cpp3
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp5
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp27
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp7
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp8
-rw-r--r--lib/CodeGen/StackColoring.cpp19
-rw-r--r--lib/CodeGen/TargetLoweringObjectFileImpl.cpp20
11 files changed, 142 insertions, 31 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 84162ace41..c73071e12b 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -159,6 +159,11 @@ bool AsmPrinter::doInitialization(Module &M) {
MMI = getAnalysisIfAvailable<MachineModuleInfo>();
MMI->AnalyzeModule(M);
+ // @LOCALMOD-BEGIN
+ IsPlainObject =
+ (MMI->getModule()->getOutputFormat() == Module::ObjectOutputFormat);
+ // @LOCALMOD-END
+
// Initialize TargetLoweringObjectFile.
const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
.Initialize(OutContext, TM);
@@ -275,6 +280,17 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
MCSymbol *GVSym = Mang->getSymbol(GV);
EmitVisibility(GVSym, GV->getVisibility(), !GV->isDeclaration());
+ // @LOCALMOD-BEGIN
+ // For .pexe and .pso files, emit ELF type STT_OBJECT or STT_TLS instead
+ // of NOTYPE for undefined symbols.
+ // BUG= http://code.google.com/p/nativeclient/issues/detail?id=2527
+ if (!GV->hasInitializer() && !IsPlainObject) {
+ OutStreamer.EmitSymbolAttribute(GVSym,
+ GV->isThreadLocal() ? MCSA_ELF_TypeTLS
+ : MCSA_ELF_TypeObject);
+ }
+ // @LOCALMOD-END
+
if (!GV->hasInitializer()) // External globals require no extra code.
return;
@@ -689,9 +705,14 @@ void AsmPrinter::EmitFunctionBody() {
break;
case TargetOpcode::EH_LABEL:
- case TargetOpcode::GC_LABEL:
+ case TargetOpcode::GC_LABEL: {
+ // @LOCALMOD-START
+ unsigned LabelAlign = GetTargetLabelAlign(II);
+ if (LabelAlign) EmitAlignment(LabelAlign);
+ // @LOCALMOD-END
OutStreamer.EmitLabel(II->getOperand(0).getMCSymbol());
break;
+ }
case TargetOpcode::INLINEASM:
EmitInlineAsm(II);
break;
@@ -856,6 +877,16 @@ bool AsmPrinter::doFinalization(Module &M) {
const Function &F = *I;
if (!F.isDeclaration())
continue;
+
+ // @LOCALMOD-BEGIN
+ // For .pexe and .pso files, emit STT_FUNC for function declarations.
+ // BUG= http://code.google.com/p/nativeclient/issues/detail?id=2527
+ if (!IsPlainObject) {
+ OutStreamer.EmitSymbolAttribute(Mang->getSymbol(&F),
+ MCSA_ELF_TypeFunction);
+ }
+ // @LOCALMOD-END
+
GlobalValue::VisibilityTypes V = F.getVisibility();
if (V == GlobalValue::DefaultVisibility)
continue;
@@ -1075,12 +1106,25 @@ void AsmPrinter::EmitJumpTableInfo() {
if (// In PIC mode, we need to emit the jump table to the same section as the
// function body itself, otherwise the label differences won't make sense.
// FIXME: Need a better predicate for this: what about custom entries?
- MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 ||
+ (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 ||
// We should also do if the section name is NULL or function is declared
// in discardable section
// FIXME: this isn't the right predicate, should be based on the MCSection
// for the function.
- F->isWeakForLinker()) {
+ // @LOCALMOD-START
+ // the original code is a hack
+ // jumptables usually end up in .rodata
+ // but for functions with weak linkage there is a chance that the are
+ // not needed. So in order to be discard the function AND the jumptable
+ // they keep them both in .text. This fix only works if we never discard
+ // weak functions. This is guaranteed because the bitcode linker already
+ // throws out unused ones.
+ // TODO: Investigate the other case of concern -- PIC code.
+ // Concern is about jumptables being in a different section: can the
+ // rodata and text be too far apart for a RIP-relative offset?
+ F->isWeakForLinker())
+ && !UseReadOnlyJumpTables()) {
+ // @LOCALMOD-END
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F,Mang,TM));
} else {
// Otherwise, drop it in the readonly section.
@@ -1107,7 +1151,7 @@ void AsmPrinter::EmitJumpTableInfo() {
// .set directive for each unique entry. This reduces the number of
// relocations the assembler will generate for the jump table.
if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 &&
- MAI->hasSetDirective()) {
+ MAI->hasSetDirective() && !UseReadOnlyJumpTables()) { // @LOCALMOD
SmallPtrSet<const MachineBasicBlock*, 16> EmittedSets;
const TargetLowering *TLI = TM.getTargetLowering();
const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF,JTI,OutContext);
@@ -1190,7 +1234,7 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
// If we have emitted set directives for the jump table entries, print
// them rather than the entries themselves. If we're emitting PIC, then
// emit the table entries as differences between two text section labels.
- if (MAI->hasSetDirective()) {
+ if (MAI->hasSetDirective() && !UseReadOnlyJumpTables()) { // @LOCALMOD
// If we used .set, reference the .set's symbol.
Value = MCSymbolRefExpr::Create(GetJTSetSymbol(UID, MBB->getNumber()),
OutContext);
@@ -1210,7 +1254,6 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
OutStreamer.EmitValue(Value, EntrySize);
}
-
/// EmitSpecialLLVMGlobal - Check to see if the specified global is a
/// special global used by LLVM. If so, emit it and return true, otherwise
/// do nothing and return false.
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index abfa330fa2..e2425d742b 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -70,6 +70,11 @@ static void srcMgrDiagHandler(const SMDiagnostic &Diag, void *diagInfo) {
/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
InlineAsm::AsmDialect Dialect) const {
+#if defined(__native_client__)
+ // Prune the generic AsmParser bits from the in-browser translator.
+ // This is normally used to parse inline asm (see createMCAsmParser below).
+ return;
+#else
assert(!Str.empty() && "Can't emit empty inline asm block");
// Remember if the buffer is nul terminated or not so we can avoid a copy.
@@ -135,6 +140,7 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
/*NoFinalize*/ true);
if (Res && !HasDiagHandler)
report_fatal_error("Error parsing inline asm\n");
+#endif // defined(__native_client__)
}
static void EmitMSInlineAsmStr(const char *AsmStr, const MachineInstr *MI,
@@ -411,6 +417,10 @@ static void EmitGCCInlineAsmStr(const char *AsmStr, const MachineInstr *MI,
/// EmitInlineAsm - This method formats and emits the specified machine
/// instruction that is an inline asm.
void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const {
+#if defined(__native__client__)
+ // See above LOCALMOD for pruning generic AsmParsing.
+ return;
+#else
assert(MI->isInlineAsm() && "printInlineAsm only works on inline asms");
// Count the number of register definitions to find the asm string.
@@ -480,6 +490,7 @@ void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const {
if (OutStreamer.hasRawTextSupport())
OutStreamer.EmitRawText(Twine("\t")+MAI->getCommentString()+
MAI->getInlineAsmEnd());
+#endif // __native_client__
}
@@ -550,4 +561,3 @@ bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
// Target doesn't support this yet!
return true;
}
-
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp
index f8cc3b3999..43b5c7d78d 100644
--- a/lib/CodeGen/BranchFolding.cpp
+++ b/lib/CodeGen/BranchFolding.cpp
@@ -21,6 +21,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
+#include "llvm/CodeGen/MachineConstantPool.h" // @LOCALMOD
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
@@ -233,6 +234,21 @@ bool BranchFolder::OptimizeFunction(MachineFunction &MF,
}
}
+ // @LOCALMOD-START
+ // This currently only used on ARM targets where the ConstantPool
+ // subclass is overloading getJumpTableIndex()
+ const std::vector<MachineConstantPoolEntry>& CPs =
+ MF.getConstantPool()->getConstants();
+ for (unsigned i = 0, e = CPs.size(); i != e; ++i) {
+ if (!CPs[i].isMachineConstantPoolEntry()) continue;
+ unsigned *JTIndex = CPs[i].Val.MachineCPVal->getJumpTableIndex();
+ if (!JTIndex) continue;
+ // Remember that this JT is live.
+ JTIsLive.set(*JTIndex);
+ }
+ // @LOCALMOD-END
+
+
// Finally, remove dead jump tables. This happens when the
// indirect jump was unreachable (and thus deleted).
for (unsigned i = 0, e = JTIsLive.size(); i != e; ++i)
diff --git a/lib/CodeGen/CallingConvLower.cpp b/lib/CodeGen/CallingConvLower.cpp
index 75f4b96e3b..d4cc1a8654 100644
--- a/lib/CodeGen/CallingConvLower.cpp
+++ b/lib/CodeGen/CallingConvLower.cpp
@@ -33,6 +33,7 @@ CCState::CCState(CallingConv::ID CC, bool isVarArg, MachineFunction &mf,
StackOffset = 0;
clearByValRegsInfo();
+ clearHasByValInRegPosition(); // @LOCALMOD.
UsedRegs.resize((TRI.getNumRegs()+31)/32);
}
diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp
index 78e9950e5e..71a377df09 100644
--- a/lib/CodeGen/MachineBasicBlock.cpp
+++ b/lib/CodeGen/MachineBasicBlock.cpp
@@ -170,7 +170,8 @@ MachineBasicBlock::SkipPHIsAndLabels(MachineBasicBlock::iterator I) {
MachineBasicBlock::iterator MachineBasicBlock::getFirstTerminator() {
iterator B = begin(), E = end(), I = E;
- while (I != B && ((--I)->isTerminator() || I->isDebugValue()))
+ while (I != B && ((--I)->isTerminator() || I->isDebugValue()
+ || I->getOpcode() == TargetOpcode::BUNDLE_UNLOCK)) // @LOCALMOD
; /*noop */
while (I != E && !I->isTerminator())
++I;
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index 959dd7df58..337b9790a5 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -29,6 +29,7 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h" // @LOCALMOD (upstreamable)
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/IR/InlineAsm.h"
@@ -214,7 +215,9 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &F) {
std::vector<CalleeSavedInfo> CSI;
for (unsigned i = 0; CSRegs[i]; ++i) {
unsigned Reg = CSRegs[i];
- if (F.getRegInfo().isPhysRegUsed(Reg)) {
+ // @LOCALMOD (but upstreamable)
+ // Functions which call __builtin_unwind_init get all their registers saved.
+ if (F.getRegInfo().isPhysRegUsed(Reg) || F.getMMI().callsUnwindInit()) {
// If the reg is modified, save it!
CSI.push_back(CalleeSavedInfo(Reg));
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 67db211ec4..9d02fc7323 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -5191,6 +5191,28 @@ SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I, unsigned Intrinsic) {
case Intrinsic::donothing:
// ignore
return 0;
+ // @LOCALMOD-BEGIN
+ // Native Client Intrinsics for TLS setup / layout.
+ case Intrinsic::nacl_tp_tls_offset: {
+ SDValue tls_size = getValue(I.getArgOperand(0));
+ setValue(&I, DAG.getNode(ISD::NACL_TP_TLS_OFFSET, dl,
+ tls_size.getValueType(),
+ tls_size));
+ return 0;
+ }
+ case Intrinsic::nacl_tp_tdb_offset: {
+ SDValue tdb_size = getValue(I.getArgOperand(0));
+ setValue(&I, DAG.getNode(ISD::NACL_TP_TDB_OFFSET, dl,
+ tdb_size.getValueType(),
+ tdb_size));
+ return 0;
+ }
+ case Intrinsic::nacl_target_arch: {
+ EVT DestVT = TLI.getValueType(I.getType());
+ setValue(&I, DAG.getNode(ISD::NACL_TARGET_ARCH, dl, DestVT));
+ return 0;
+ }
+ // @LOCALMOD-END
}
}
@@ -6376,7 +6398,10 @@ void SelectionDAGBuilder::visitVAArg(const VAArgInst &I) {
SDValue V = DAG.getVAArg(TLI.getValueType(I.getType()), getCurDebugLoc(),
getRoot(), getValue(I.getOperand(0)),
DAG.getSrcValue(I.getOperand(0)),
- TD.getABITypeAlignment(I.getType()));
+// @LOCALMOD-BEGIN
+ TD.getCallFrameTypeAlignment(I.getType()));
+// @LOCALMOD-END
+
setValue(&I, V);
DAG.setRoot(V.getValue(1));
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
index 47b0391850..50b5bccf7c 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
@@ -313,6 +313,13 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
case ISD::SETFALSE: return "setfalse";
case ISD::SETFALSE2: return "setfalse2";
}
+
+ // @LOCALMOD-BEGIN
+ // NaCl intrinsics for TLS setup
+ case ISD::NACL_TP_TLS_OFFSET: return "nacl_tls_offset";
+ case ISD::NACL_TP_TDB_OFFSET: return "nacl_tdb_offset";
+ case ISD::NACL_TARGET_ARCH: return "nacl_target_arch";
+ // @LOCALMOD-END
}
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index e21f26e91c..02b838234d 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -585,7 +585,6 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
}
DEBUG(dbgs() << "Initial selection DAG: BB#" << BlockNumber
<< " '" << BlockName << "'\n"; CurDAG->dump());
-
if (ViewDAGCombine1) CurDAG->viewGraph("dag-combine1 input for " + BlockName);
// Run the DAG combiner in pre-legalize mode.
@@ -614,7 +613,6 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
if (Changed) {
if (ViewDAGCombineLT)
CurDAG->viewGraph("dag-combine-lt input for " + BlockName);
-
// Run the DAG combiner in post-type-legalize mode.
{
NamedRegionTimer T("DAG Combining after legalize types", GroupName,
@@ -636,10 +634,8 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
NamedRegionTimer T("Type Legalization 2", GroupName, TimePassesIsEnabled);
CurDAG->LegalizeTypes();
}
-
if (ViewDAGCombineLT)
CurDAG->viewGraph("dag-combine-lv input for " + BlockName);
-
// Run the DAG combiner in post-type-legalize mode.
{
NamedRegionTimer T("DAG Combining after legalize vectors", GroupName,
@@ -650,19 +646,15 @@ void SelectionDAGISel::CodeGenAndEmitDAG() {
DEBUG(dbgs() << "Optimized vector-legalized selection DAG: BB#"
<< BlockNumber << " '" << BlockName << "'\n"; CurDAG->dump());
}
-
if (ViewLegalizeDAGs) CurDAG->viewGraph("legalize input for " + BlockName);
-
{
NamedRegionTimer T("DAG Legalization", GroupName, TimePassesIsEnabled);
CurDAG->Legalize();
}
-
DEBUG(dbgs() << "Legalized selection DAG: BB#" << BlockNumber
<< " '" << BlockName << "'\n"; CurDAG->dump());
if (ViewDAGCombine2) CurDAG->viewGraph("dag-combine2 input for " + BlockName);
-
// Run the DAG combiner in post-legalize mode.
{
NamedRegionTimer T("DAG Combining 2", GroupName, TimePassesIsEnabled);
diff --git a/lib/CodeGen/StackColoring.cpp b/lib/CodeGen/StackColoring.cpp
index a789a2596d..4b7e4609e5 100644
--- a/lib/CodeGen/StackColoring.cpp
+++ b/lib/CodeGen/StackColoring.cpp
@@ -428,17 +428,14 @@ void StackColoring::calculateLiveIntervals(unsigned NumSlots) {
}
// Create the interval of the blocks that we previously found to be 'alive'.
- BitVector Alive = BlockLiveness[MBB].LiveIn;
- Alive |= BlockLiveness[MBB].LiveOut;
-
- if (Alive.any()) {
- for (int pos = Alive.find_first(); pos != -1;
- pos = Alive.find_next(pos)) {
- if (!Starts[pos].isValid())
- Starts[pos] = Indexes->getMBBStartIdx(MBB);
- if (!Finishes[pos].isValid())
- Finishes[pos] = Indexes->getMBBEndIdx(MBB);
- }
+ BlockLifetimeInfo &MBBLiveness = BlockLiveness[MBB];
+ for (int pos = MBBLiveness.LiveIn.find_first(); pos != -1;
+ pos = MBBLiveness.LiveIn.find_next(pos)) {
+ Starts[pos] = Indexes->getMBBStartIdx(MBB);
+ }
+ for (int pos = MBBLiveness.LiveOut.find_first(); pos != -1;
+ pos = MBBLiveness.LiveOut.find_next(pos)) {
+ Finishes[pos] = Indexes->getMBBEndIdx(MBB);
}
for (unsigned i = 0; i < NumSlots; ++i) {
diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 7e7359a8fe..f91688531b 100644
--- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -54,8 +54,16 @@ TargetLoweringObjectFileELF::getCFIPersonalitySymbol(const GlobalValue *GV,
case dwarf::DW_EH_PE_absptr:
return Mang->getSymbol(GV);
case dwarf::DW_EH_PE_pcrel: {
+ // @LOCALMOD-BEGIN
+ // The dwarf section label should not include the version suffix.
+ // Strip it off here.
+ StringRef Name = Mang->getSymbol(GV)->getName();
+ size_t atpos = Name.find("@");
+ if (atpos != StringRef::npos)
+ Name = Name.substr(0, atpos);
+ // @LOCALMOD-END
return getContext().GetOrCreateSymbol(StringRef("DW.ref.") +
- Mang->getSymbol(GV)->getName());
+ Name); // @LOCALMOD
}
}
}
@@ -64,7 +72,15 @@ void TargetLoweringObjectFileELF::emitPersonalityValue(MCStreamer &Streamer,
const TargetMachine &TM,
const MCSymbol *Sym) const {
SmallString<64> NameData("DW.ref.");
- NameData += Sym->getName();
+ // @LOCALMOD-BEGIN
+ // The dwarf section label should not include the version suffix.
+ // Strip it off here.
+ StringRef Name = Sym->getName();
+ size_t atpos = Name.find("@");
+ if (atpos != StringRef::npos)
+ Name = Name.substr(0, atpos);
+ // @LOCALMOD-END
+ NameData += Name; // @LOCALMOD
MCSymbol *Label = getContext().GetOrCreateSymbol(NameData);
Streamer.EmitSymbolAttribute(Label, MCSA_Hidden);
Streamer.EmitSymbolAttribute(Label, MCSA_Weak);