[llvm-commits] [llvm] r112260 - /llvm/trunk/lib/MC/MCELFStreamer.cpp
Benjamin Kramer
benny.kra at googlemail.com
Fri Aug 27 03:40:51 PDT 2010
Author: d0k
Date: Fri Aug 27 05:40:51 2010
New Revision: 112260
URL: http://llvm.org/viewvc/llvm-project?rev=112260&view=rev
Log:
MCELF: Port EmitInstruction changes from MachO streamer. Patch by Roman Divacky.
Modified:
llvm/trunk/lib/MC/MCELFStreamer.cpp
Modified: llvm/trunk/lib/MC/MCELFStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFStreamer.cpp?rev=112260&r1=112259&r2=112260&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCELFStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCELFStreamer.cpp Fri Aug 27 05:40:51 2010
@@ -34,6 +34,8 @@
namespace {
class MCELFStreamer : public MCObjectStreamer {
+ void EmitInstToFragment(const MCInst &Inst);
+ void EmitInstToData(const MCInst &Inst);
public:
MCELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *Emitter)
@@ -328,16 +330,25 @@
SD.setFlags(ELF_STT_File | ELF_STB_Local | ELF_STV_Default);
}
-void MCELFStreamer::EmitInstruction(const MCInst &Inst) {
- // Scan for values.
- for (unsigned i = 0; i != Inst.getNumOperands(); ++i)
- if (Inst.getOperand(i).isExpr())
- AddValueSymbols(Inst.getOperand(i).getExpr());
+void MCELFStreamer::EmitInstToFragment(const MCInst &Inst) {
+ MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
- getCurrentSectionData()->setHasInstructions(true);
+ // Add the fixups and data.
+ //
+ // FIXME: Revisit this design decision when relaxation is done, we may be
+ // able to get away with not storing any extra data in the MCInst.
+ SmallVector<MCFixup, 4> Fixups;
+ SmallString<256> Code;
+ raw_svector_ostream VecOS(Code);
+ getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
+ VecOS.flush();
- // FIXME-PERF: Common case is that we don't need to relax, encode directly
- // onto the data fragments buffers.
+ IF->getCode() = Code;
+ IF->getFixups() = Fixups;
+}
+
+void MCELFStreamer::EmitInstToData(const MCInst &Inst) {
+ MCDataFragment *DF = getOrCreateDataFragment();
SmallVector<MCFixup, 4> Fixups;
SmallString<256> Code;
@@ -345,47 +356,41 @@
getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
VecOS.flush();
- // FIXME: Eliminate this copy.
- SmallVector<MCFixup, 4> AsmFixups;
+ // Add the fixups and data.
for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
- MCFixup &F = Fixups[i];
- AsmFixups.push_back(MCFixup::Create(F.getOffset(), F.getValue(),
- F.getKind()));
+ Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
+ DF->addFixup(Fixups[i]);
}
+ DF->getContents().append(Code.begin(), Code.end());
+}
- // See if we might need to relax this instruction, if so it needs its own
- // fragment.
- //
- // FIXME-PERF: Support target hook to do a fast path that avoids the encoder,
- // when we can immediately tell that we will get something which might need
- // relaxation (and compute its size).
- //
- // FIXME-PERF: We should also be smart about immediately relaxing instructions
- // which we can already show will never possibly fit (we can also do a very
- // good job of this before we do the first relaxation pass, because we have
- // total knowledge about undefined symbols at that point). Even now, though,
- // we can do a decent job, especially on Darwin where scattering means that we
- // are going to often know that we can never fully resolve a fixup.
- if (getAssembler().getBackend().MayNeedRelaxation(Inst)) {
- MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
-
- // Add the fixups and data.
- //
- // FIXME: Revisit this design decision when relaxation is done, we may be
- // able to get away with not storing any extra data in the MCInst.
- IF->getCode() = Code;
- IF->getFixups() = AsmFixups;
+void MCELFStreamer::EmitInstruction(const MCInst &Inst) {
+ // Scan for values.
+ for (unsigned i = 0; i != Inst.getNumOperands(); ++i)
+ if (Inst.getOperand(i).isExpr())
+ AddValueSymbols(Inst.getOperand(i).getExpr());
+
+ getCurrentSectionData()->setHasInstructions(true);
+ // If this instruction doesn't need relaxation, just emit it as data.
+ if (!getAssembler().getBackend().MayNeedRelaxation(Inst)) {
+ EmitInstToData(Inst);
return;
}
- // Add the fixups and data.
- MCDataFragment *DF = getOrCreateDataFragment();
- for (unsigned i = 0, e = AsmFixups.size(); i != e; ++i) {
- AsmFixups[i].setOffset(AsmFixups[i].getOffset() + DF->getContents().size());
- DF->addFixup(AsmFixups[i]);
+ // Otherwise, if we are relaxing everything, relax the instruction as much as
+ // possible and emit it as data.
+ if (getAssembler().getRelaxAll()) {
+ MCInst Relaxed;
+ getAssembler().getBackend().RelaxInstruction(Inst, Relaxed);
+ while (getAssembler().getBackend().MayNeedRelaxation(Relaxed))
+ getAssembler().getBackend().RelaxInstruction(Relaxed, Relaxed);
+ EmitInstToData(Relaxed);
+ return;
}
- DF->getContents().append(Code.begin(), Code.end());
+
+ // Otherwise emit to a separate fragment.
+ EmitInstToFragment(Inst);
}
void MCELFStreamer::Finish() {
More information about the llvm-commits
mailing list