diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 55 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp | 12 | ||||
-rw-r--r-- | lib/CodeGen/BranchFolding.cpp | 16 | ||||
-rw-r--r-- | lib/CodeGen/CallingConvLower.cpp | 1 | ||||
-rw-r--r-- | lib/CodeGen/MachineBasicBlock.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/PrologEpilogInserter.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 27 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp | 7 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 8 | ||||
-rw-r--r-- | lib/CodeGen/StackColoring.cpp | 19 | ||||
-rw-r--r-- | lib/CodeGen/TargetLoweringObjectFileImpl.cpp | 20 |
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); |