OLD | NEW |
1 //===- lib/MC/MCAssembler.cpp - Assembler Backend Implementation ----------===// | 1 //===- lib/MC/MCAssembler.cpp - Assembler Backend Implementation ----------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 | 9 |
10 #define DEBUG_TYPE "assembler" | 10 #define DEBUG_TYPE "assembler" |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 unsigned NextIndex = 0; | 106 unsigned NextIndex = 0; |
107 if (LastValidFragment) | 107 if (LastValidFragment) |
108 NextIndex = LastValidFragment->getParent()->getLayoutOrder() + 1; | 108 NextIndex = LastValidFragment->getParent()->getLayoutOrder() + 1; |
109 Cur = SectionOrder[NextIndex]->begin(); | 109 Cur = SectionOrder[NextIndex]->begin(); |
110 } | 110 } |
111 | 111 |
112 const_cast<MCAsmLayout*>(this)->LayoutFragment(Cur); | 112 const_cast<MCAsmLayout*>(this)->LayoutFragment(Cur); |
113 } | 113 } |
114 } | 114 } |
115 | 115 |
116 void MCAsmLayout::FragmentReplaced(MCFragment *Src, MCFragment *Dst) { | 116 void MCAsmLayout::ReplaceFragment(MCFragment *Src, MCFragment *Dst) { |
| 117 MCSectionData *SD = Src->getParent(); |
| 118 |
| 119 // Insert Dst immediately before Src |
| 120 SD->getFragmentList().insert(Src, Dst); |
| 121 |
| 122 // Set the data fragment's layout data. |
| 123 Dst->setParent(Src->getParent()); |
| 124 Dst->setAtom(Src->getAtom()); |
| 125 Dst->setLayoutOrder(Src->getLayoutOrder()); |
| 126 |
117 if (LastValidFragment == Src) | 127 if (LastValidFragment == Src) |
118 LastValidFragment = Dst; | 128 LastValidFragment = Dst; |
119 | 129 |
120 Dst->Offset = Src->Offset; | 130 Dst->Offset = Src->Offset; |
121 Dst->EffectiveSize = Src->EffectiveSize; | 131 Dst->EffectiveSize = Src->EffectiveSize; |
| 132 |
| 133 // Remove Src, but don't delete it yet. |
| 134 SD->getFragmentList().remove(Src); |
| 135 } |
| 136 |
| 137 void MCAsmLayout::CoalesceFragments(MCFragment *Src, MCFragment *Dst) { |
| 138 assert(Src->getPrevNode() == Dst); |
| 139 |
| 140 if (isFragmentUpToDate(Src)) { |
| 141 if (LastValidFragment == Src) |
| 142 LastValidFragment = Dst; |
| 143 Dst->EffectiveSize += Src->EffectiveSize; |
| 144 } else { |
| 145 // We don't know the effective size of Src, so we have to invalidate Dst. |
| 146 UpdateForSlide(Dst, 0); |
| 147 } |
| 148 // Remove Src, but don't delete it yet. |
| 149 Src->getParent()->getFragmentList().remove(Src); |
122 } | 150 } |
123 | 151 |
124 uint64_t MCAsmLayout::getFragmentAddress(const MCFragment *F) const { | 152 uint64_t MCAsmLayout::getFragmentAddress(const MCFragment *F) const { |
125 assert(F->getParent() && "Missing section()!"); | 153 assert(F->getParent() && "Missing section()!"); |
126 return getSectionAddress(F->getParent()) + getFragmentOffset(F); | 154 return getSectionAddress(F->getParent()) + getFragmentOffset(F); |
127 } | 155 } |
128 | 156 |
129 uint64_t MCAsmLayout::getFragmentEffectiveSize(const MCFragment *F) const { | 157 uint64_t MCAsmLayout::getFragmentEffectiveSize(const MCFragment *F) const { |
130 EnsureValid(F); | 158 EnsureValid(F); |
131 assert(F->EffectiveSize != ~UINT64_C(0) && "Address not set!"); | 159 assert(F->EffectiveSize != ~UINT64_C(0) && "Address not set!"); |
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 case MCFragment::FT_LEB: | 909 case MCFragment::FT_LEB: |
882 WasRelaxed |= RelaxLEB(Writer, Layout, *cast<MCLEBFragment>(it2)); | 910 WasRelaxed |= RelaxLEB(Writer, Layout, *cast<MCLEBFragment>(it2)); |
883 break; | 911 break; |
884 } | 912 } |
885 } | 913 } |
886 } | 914 } |
887 | 915 |
888 return WasRelaxed; | 916 return WasRelaxed; |
889 } | 917 } |
890 | 918 |
| 919 static void LowerInstFragment(MCInstFragment *IF, |
| 920 MCDataFragment *DF) { |
| 921 |
| 922 uint64_t DataOffset = DF->getContents().size(); |
| 923 |
| 924 // Copy in the data |
| 925 DF->getContents().append(IF->getCode().begin(), IF->getCode().end()); |
| 926 |
| 927 // Adjust the fixup offsets and add them to the data fragment. |
| 928 for (unsigned i = 0, e = IF->getFixups().size(); i != e; ++i) { |
| 929 MCFixup &F = IF->getFixups()[i]; |
| 930 F.setOffset(DataOffset + F.getOffset()); |
| 931 DF->getFixups().push_back(F); |
| 932 } |
| 933 } |
| 934 |
891 void MCAssembler::FinishLayout(MCAsmLayout &Layout) { | 935 void MCAssembler::FinishLayout(MCAsmLayout &Layout) { |
892 // Lower out any instruction fragments, to simplify the fixup application and | 936 // Lower out any instruction fragments, to simplify the fixup application and |
893 // output. | 937 // output. |
894 // | 938 // |
895 // FIXME-PERF: We don't have to do this, but the assumption is that it is | 939 // FIXME-PERF: We don't have to do this, but the assumption is that it is |
896 // cheap (we will mostly end up eliminating fragments and appending on to data | 940 // cheap (we will mostly end up eliminating fragments and appending on to data |
897 // fragments), so the extra complexity downstream isn't worth it. Evaluate | 941 // fragments), so the extra complexity downstream isn't worth it. Evaluate |
898 // this assumption. | 942 // this assumption. |
899 for (iterator it = begin(), ie = end(); it != ie; ++it) { | 943 unsigned FragmentIndex = 0; |
900 MCSectionData &SD = *it; | 944 for (unsigned i = 0, e = Layout.getSectionOrder().size(); i != e; ++i) { |
| 945 MCSectionData &SD = *Layout.getSectionOrder()[i]; |
| 946 MCDataFragment *CurDF = NULL; |
901 | 947 |
902 for (MCSectionData::iterator it2 = SD.begin(), | 948 for (MCSectionData::iterator it2 = SD.begin(), |
903 ie2 = SD.end(); it2 != ie2; ++it2) { | 949 ie2 = SD.end(); it2 != ie2; ++it2) { |
904 MCInstFragment *IF = dyn_cast<MCInstFragment>(it2); | 950 switch (it2->getKind()) { |
905 if (!IF) | 951 default: |
906 continue; | 952 CurDF = NULL; |
| 953 break; |
| 954 case MCFragment::FT_Data: |
| 955 CurDF = cast<MCDataFragment>(it2); |
| 956 break; |
| 957 case MCFragment::FT_Inst: { |
| 958 MCInstFragment *IF = cast<MCInstFragment>(it2); |
| 959 // Use the existing data fragment if possible. |
| 960 if (CurDF && CurDF->getAtom() == IF->getAtom()) { |
| 961 Layout.CoalesceFragments(IF, CurDF); |
| 962 } else { |
| 963 // Otherwise, create a new data fragment. |
| 964 CurDF = new MCDataFragment(); |
| 965 Layout.ReplaceFragment(IF, CurDF); |
| 966 } |
907 | 967 |
908 // Create a new data fragment for the instruction. | 968 // Lower the Instruction Fragment |
909 // | 969 LowerInstFragment(IF, CurDF); |
910 // FIXME-PERF: Reuse previous data fragment if possible. | |
911 MCDataFragment *DF = new MCDataFragment(); | |
912 SD.getFragmentList().insert(it2, DF); | |
913 | 970 |
914 // Update the data fragments layout data. | 971 // Delete the instruction fragment and update the iterator. |
915 DF->setParent(IF->getParent()); | 972 delete IF; |
916 DF->setAtom(IF->getAtom()); | 973 it2 = CurDF; |
917 DF->setLayoutOrder(IF->getLayoutOrder()); | 974 break; |
918 Layout.FragmentReplaced(IF, DF); | 975 } |
919 | 976 } |
920 // Copy in the data and the fixups. | 977 // Since we may have merged fragments, fix the layout order. |
921 DF->getContents().append(IF->getCode().begin(), IF->getCode().end()); | 978 it2->setLayoutOrder(FragmentIndex++); |
922 for (unsigned i = 0, e = IF->getFixups().size(); i != e; ++i) | |
923 DF->getFixups().push_back(IF->getFixups()[i]); | |
924 | |
925 // Delete the instruction fragment and update the iterator. | |
926 SD.getFragmentList().erase(IF); | |
927 it2 = DF; | |
928 } | 979 } |
929 } | 980 } |
930 } | 981 } |
931 | 982 |
932 // Debugging methods | 983 // Debugging methods |
933 | 984 |
934 namespace llvm { | 985 namespace llvm { |
935 | 986 |
936 raw_ostream &operator<<(raw_ostream &OS, const MCFixup &AF) { | 987 raw_ostream &operator<<(raw_ostream &OS, const MCFixup &AF) { |
937 OS << "<MCFixup" << " Offset:" << AF.getOffset() | 988 OS << "<MCFixup" << " Offset:" << AF.getOffset() |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1071 } | 1122 } |
1072 OS << "],\n"; | 1123 OS << "],\n"; |
1073 OS << " Symbols:["; | 1124 OS << " Symbols:["; |
1074 | 1125 |
1075 for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) { | 1126 for (symbol_iterator it = symbol_begin(), ie = symbol_end(); it != ie; ++it) { |
1076 if (it != symbol_begin()) OS << ",\n "; | 1127 if (it != symbol_begin()) OS << ",\n "; |
1077 it->dump(); | 1128 it->dump(); |
1078 } | 1129 } |
1079 OS << "]>\n"; | 1130 OS << "]>\n"; |
1080 } | 1131 } |
OLD | NEW |