llvm.org GIT mirror llvm / d5c1fb9
Move some dwarf emission routines to AsmPrinterDwarf.cpp. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203191 91177308-0d34-0410-b5e6-96231b3b80d8 Eric Christopher 5 years ago
2 changed file(s) with 157 addition(s) and 156 deletion(s). Raw diff Collapse all Expand all
1515 #include "DwarfDebug.h"
1616 #include "DwarfException.h"
1717 #include "WinCodeViewLineTables.h"
18 #include "llvm/ADT/SmallBitVector.h"
1918 #include "llvm/ADT/SmallString.h"
2019 #include "llvm/ADT/Statistic.h"
2120 #include "llvm/Analysis/ConstantFolding.h"
871870 OutStreamer.AddBlankLine();
872871 }
873872
874 /// Emit a dwarf register operation.
875 static void emitDwarfRegOp(const AsmPrinter &AP, int Reg) {
876 assert(Reg >= 0);
877 if (Reg < 32) {
878 AP.OutStreamer.AddComment(
879 dwarf::OperationEncodingString(dwarf::DW_OP_reg0 + Reg));
880 AP.EmitInt8(dwarf::DW_OP_reg0 + Reg);
881 } else {
882 AP.OutStreamer.AddComment("DW_OP_regx");
883 AP.EmitInt8(dwarf::DW_OP_regx);
884 AP.OutStreamer.AddComment(Twine(Reg));
885 AP.EmitULEB128(Reg);
886 }
887 }
888
889 /// Emit an (double-)indirect dwarf register operation.
890 static void emitDwarfRegOpIndirect(const AsmPrinter &AP,
891 int Reg, int Offset, bool Deref) {
892 assert(Reg >= 0);
893 if (Reg < 32) {
894 AP.OutStreamer.AddComment(
895 dwarf::OperationEncodingString(dwarf::DW_OP_breg0 + Reg));
896 AP.EmitInt8(dwarf::DW_OP_breg0 + Reg);
897 } else {
898 AP.OutStreamer.AddComment("DW_OP_bregx");
899 AP.EmitInt8(dwarf::DW_OP_bregx);
900 AP.OutStreamer.AddComment(Twine(Reg));
901 AP.EmitULEB128(Reg);
902 }
903 AP.EmitSLEB128(Offset);
904 if (Deref)
905 AP.EmitInt8(dwarf::DW_OP_deref);
906 }
907
908 /// Emit a dwarf register operation for describing
909 /// - a small value occupying only part of a register or
910 /// - a small register representing only part of a value.
911 static void emitDwarfOpPiece(const AsmPrinter &AP,
912 unsigned Size, unsigned Offset) {
913 assert(Size > 0);
914 if (Offset > 0) {
915 AP.OutStreamer.AddComment("DW_OP_bit_piece");
916 AP.EmitInt8(dwarf::DW_OP_bit_piece);
917 AP.OutStreamer.AddComment(Twine(Size));
918 AP.EmitULEB128(Size);
919 AP.OutStreamer.AddComment(Twine(Offset));
920 AP.EmitULEB128(Offset);
921 } else {
922 AP.OutStreamer.AddComment("DW_OP_piece");
923 AP.EmitInt8(dwarf::DW_OP_piece);
924 unsigned ByteSize = Size / 8; // Assuming 8 bits per byte.
925 AP.OutStreamer.AddComment(Twine(ByteSize));
926 AP.EmitULEB128(ByteSize);
927 }
928 }
929
930 /// Some targets do not provide a DWARF register number for every
931 /// register. This function attempts to emit a dwarf register by
932 /// emitting a piece of a super-register or by piecing together
933 /// multiple subregisters that alias the register.
934 static void EmitDwarfRegOpPiece(const AsmPrinter &AP,
935 const MachineLocation &MLoc) {
936 assert(!MLoc.isIndirect());
937 const TargetRegisterInfo *TRI = AP.TM.getRegisterInfo();
938 int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false);
939
940 // Walk up the super-register chain until we find a valid number.
941 // For example, EAX on x86_64 is a 32-bit piece of RAX with offset 0.
942 for (MCSuperRegIterator SR(MLoc.getReg(), TRI); SR.isValid(); ++SR) {
943 Reg = TRI->getDwarfRegNum(*SR, false);
944 if (Reg >= 0) {
945 unsigned Idx = TRI->getSubRegIndex(*SR, MLoc.getReg());
946 unsigned Size = TRI->getSubRegIdxSize(Idx);
947 unsigned Offset = TRI->getSubRegIdxOffset(Idx);
948 AP.OutStreamer.AddComment("super-register");
949 emitDwarfRegOp(AP, Reg);
950 emitDwarfOpPiece(AP, Size, Offset);
951 return;
952 }
953 }
954
955 // Otherwise, attempt to find a covering set of sub-register numbers.
956 // For example, Q0 on ARM is a composition of D0+D1.
957 //
958 // Keep track of the current position so we can emit the more
959 // efficient DW_OP_piece.
960 unsigned CurPos = 0;
961 // The size of the register in bits, assuming 8 bits per byte.
962 unsigned RegSize = TRI->getMinimalPhysRegClass(MLoc.getReg())->getSize()*8;
963 // Keep track of the bits in the register we already emitted, so we
964 // can avoid emitting redundant aliasing subregs.
965 SmallBitVector Coverage(RegSize, false);
966 for (MCSubRegIterator SR(MLoc.getReg(), TRI); SR.isValid(); ++SR) {
967 unsigned Idx = TRI->getSubRegIndex(MLoc.getReg(), *SR);
968 unsigned Size = TRI->getSubRegIdxSize(Idx);
969 unsigned Offset = TRI->getSubRegIdxOffset(Idx);
970 Reg = TRI->getDwarfRegNum(*SR, false);
971
972 // Intersection between the bits we already emitted and the bits
973 // covered by this subregister.
974 SmallBitVector Intersection(RegSize, false);
975 Intersection.set(Offset, Offset+Size);
976 Intersection ^= Coverage;
977
978 // If this sub-register has a DWARF number and we haven't covered
979 // its range, emit a DWARF piece for it.
980 if (Reg >= 0 && Intersection.any()) {
981 AP.OutStreamer.AddComment("sub-register");
982 emitDwarfRegOp(AP, Reg);
983 emitDwarfOpPiece(AP, Size, Offset == CurPos ? 0 : Offset);
984 CurPos = Offset+Size;
985
986 // Mark it as emitted.
987 Coverage.set(Offset, Offset+Size);
988 }
989 }
990
991 if (CurPos == 0) {
992 // FIXME: We have no reasonable way of handling errors in here.
993 AP.OutStreamer.AddComment("nop (could not find a dwarf register number)");
994 AP.EmitInt8(dwarf::DW_OP_nop);
995 }
996 }
997
998 /// EmitDwarfRegOp - Emit dwarf register operation.
999 void AsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc,
1000 bool Indirect) const {
1001 const TargetRegisterInfo *TRI = TM.getRegisterInfo();
1002 int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false);
1003 if (Reg < 0) {
1004 // We assume that pointers are always in an addressable register.
1005 if (Indirect || MLoc.isIndirect()) {
1006 // FIXME: We have no reasonable way of handling errors in here. The
1007 // caller might be in the middle of a dwarf expression. We should
1008 // probably assert that Reg >= 0 once debug info generation is more
1009 // mature.
1010 OutStreamer.AddComment(
1011 "nop (invalid dwarf register number for indirect loc)");
1012 EmitInt8(dwarf::DW_OP_nop);
1013 return;
1014 }
1015
1016 // Attempt to find a valid super- or sub-register.
1017 if (!Indirect && !MLoc.isIndirect())
1018 return EmitDwarfRegOpPiece(*this, MLoc);
1019 }
1020
1021 if (MLoc.isIndirect())
1022 emitDwarfRegOpIndirect(*this, Reg, MLoc.getOffset(), Indirect);
1023 else if (Indirect)
1024 emitDwarfRegOpIndirect(*this, Reg, 0, false);
1025 else
1026 emitDwarfRegOp(*this, Reg);
1027 }
1028
1029873 bool AsmPrinter::doFinalization(Module &M) {
1030874 // Emit global variables.
1031875 for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
1212
1313 #define DEBUG_TYPE "asm-printer"
1414 #include "llvm/CodeGen/AsmPrinter.h"
15 #include "llvm/ADT/SmallBitVector.h"
1516 #include "llvm/ADT/Twine.h"
1617 #include "llvm/IR/DataLayout.h"
1718 #include "llvm/MC/MCAsmInfo.h"
182183 EmitLabelDifference(Label, SectionLabel, 4);
183184 }
184185
186
187 /// Emit a dwarf register operation.
188 static void emitDwarfRegOp(const AsmPrinter &AP, int Reg) {
189 assert(Reg >= 0);
190 if (Reg < 32) {
191 AP.OutStreamer.AddComment(
192 dwarf::OperationEncodingString(dwarf::DW_OP_reg0 + Reg));
193 AP.EmitInt8(dwarf::DW_OP_reg0 + Reg);
194 } else {
195 AP.OutStreamer.AddComment("DW_OP_regx");
196 AP.EmitInt8(dwarf::DW_OP_regx);
197 AP.OutStreamer.AddComment(Twine(Reg));
198 AP.EmitULEB128(Reg);
199 }
200 }
201
202 /// Emit an (double-)indirect dwarf register operation.
203 static void emitDwarfRegOpIndirect(const AsmPrinter &AP,
204 int Reg, int Offset, bool Deref) {
205 assert(Reg >= 0);
206 if (Reg < 32) {
207 AP.OutStreamer.AddComment(
208 dwarf::OperationEncodingString(dwarf::DW_OP_breg0 + Reg));
209 AP.EmitInt8(dwarf::DW_OP_breg0 + Reg);
210 } else {
211 AP.OutStreamer.AddComment("DW_OP_bregx");
212 AP.EmitInt8(dwarf::DW_OP_bregx);
213 AP.OutStreamer.AddComment(Twine(Reg));
214 AP.EmitULEB128(Reg);
215 }
216 AP.EmitSLEB128(Offset);
217 if (Deref)
218 AP.EmitInt8(dwarf::DW_OP_deref);
219 }
220
221 /// Emit a dwarf register operation for describing
222 /// - a small value occupying only part of a register or
223 /// - a small register representing only part of a value.
224 static void emitDwarfOpPiece(const AsmPrinter &AP,
225 unsigned Size, unsigned Offset) {
226 assert(Size > 0);
227 if (Offset > 0) {
228 AP.OutStreamer.AddComment("DW_OP_bit_piece");
229 AP.EmitInt8(dwarf::DW_OP_bit_piece);
230 AP.OutStreamer.AddComment(Twine(Size));
231 AP.EmitULEB128(Size);
232 AP.OutStreamer.AddComment(Twine(Offset));
233 AP.EmitULEB128(Offset);
234 } else {
235 AP.OutStreamer.AddComment("DW_OP_piece");
236 AP.EmitInt8(dwarf::DW_OP_piece);
237 unsigned ByteSize = Size / 8; // Assuming 8 bits per byte.
238 AP.OutStreamer.AddComment(Twine(ByteSize));
239 AP.EmitULEB128(ByteSize);
240 }
241 }
242
243 /// Some targets do not provide a DWARF register number for every
244 /// register. This function attempts to emit a dwarf register by
245 /// emitting a piece of a super-register or by piecing together
246 /// multiple subregisters that alias the register.
247 static void EmitDwarfRegOpPiece(const AsmPrinter &AP,
248 const MachineLocation &MLoc) {
249 assert(!MLoc.isIndirect());
250 const TargetRegisterInfo *TRI = AP.TM.getRegisterInfo();
251 int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false);
252
253 // Walk up the super-register chain until we find a valid number.
254 // For example, EAX on x86_64 is a 32-bit piece of RAX with offset 0.
255 for (MCSuperRegIterator SR(MLoc.getReg(), TRI); SR.isValid(); ++SR) {
256 Reg = TRI->getDwarfRegNum(*SR, false);
257 if (Reg >= 0) {
258 unsigned Idx = TRI->getSubRegIndex(*SR, MLoc.getReg());
259 unsigned Size = TRI->getSubRegIdxSize(Idx);
260 unsigned Offset = TRI->getSubRegIdxOffset(Idx);
261 AP.OutStreamer.AddComment("super-register");
262 emitDwarfRegOp(AP, Reg);
263 emitDwarfOpPiece(AP, Size, Offset);
264 return;
265 }
266 }
267
268 // Otherwise, attempt to find a covering set of sub-register numbers.
269 // For example, Q0 on ARM is a composition of D0+D1.
270 //
271 // Keep track of the current position so we can emit the more
272 // efficient DW_OP_piece.
273 unsigned CurPos = 0;
274 // The size of the register in bits, assuming 8 bits per byte.
275 unsigned RegSize = TRI->getMinimalPhysRegClass(MLoc.getReg())->getSize()*8;
276 // Keep track of the bits in the register we already emitted, so we
277 // can avoid emitting redundant aliasing subregs.
278 SmallBitVector Coverage(RegSize, false);
279 for (MCSubRegIterator SR(MLoc.getReg(), TRI); SR.isValid(); ++SR) {
280 unsigned Idx = TRI->getSubRegIndex(MLoc.getReg(), *SR);
281 unsigned Size = TRI->getSubRegIdxSize(Idx);
282 unsigned Offset = TRI->getSubRegIdxOffset(Idx);
283 Reg = TRI->getDwarfRegNum(*SR, false);
284
285 // Intersection between the bits we already emitted and the bits
286 // covered by this subregister.
287 SmallBitVector Intersection(RegSize, false);
288 Intersection.set(Offset, Offset+Size);
289 Intersection ^= Coverage;
290
291 // If this sub-register has a DWARF number and we haven't covered
292 // its range, emit a DWARF piece for it.
293 if (Reg >= 0 && Intersection.any()) {
294 AP.OutStreamer.AddComment("sub-register");
295 emitDwarfRegOp(AP, Reg);
296 emitDwarfOpPiece(AP, Size, Offset == CurPos ? 0 : Offset);
297 CurPos = Offset+Size;
298
299 // Mark it as emitted.
300 Coverage.set(Offset, Offset+Size);
301 }
302 }
303
304 if (CurPos == 0) {
305 // FIXME: We have no reasonable way of handling errors in here.
306 AP.OutStreamer.AddComment("nop (could not find a dwarf register number)");
307 AP.EmitInt8(dwarf::DW_OP_nop);
308 }
309 }
310
311 /// EmitDwarfRegOp - Emit dwarf register operation.
312 void AsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc,
313 bool Indirect) const {
314 const TargetRegisterInfo *TRI = TM.getRegisterInfo();
315 int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false);
316 if (Reg < 0) {
317 // We assume that pointers are always in an addressable register.
318 if (Indirect || MLoc.isIndirect()) {
319 // FIXME: We have no reasonable way of handling errors in here. The
320 // caller might be in the middle of a dwarf expression. We should
321 // probably assert that Reg >= 0 once debug info generation is more
322 // mature.
323 OutStreamer.AddComment(
324 "nop (invalid dwarf register number for indirect loc)");
325 EmitInt8(dwarf::DW_OP_nop);
326 return;
327 }
328
329 // Attempt to find a valid super- or sub-register.
330 if (!Indirect && !MLoc.isIndirect())
331 return EmitDwarfRegOpPiece(*this, MLoc);
332 }
333
334 if (MLoc.isIndirect())
335 emitDwarfRegOpIndirect(*this, Reg, MLoc.getOffset(), Indirect);
336 else if (Indirect)
337 emitDwarfRegOpIndirect(*this, Reg, 0, false);
338 else
339 emitDwarfRegOp(*this, Reg);
340 }
341
185342 //===----------------------------------------------------------------------===//
186343 // Dwarf Lowering Routines
187344 //===----------------------------------------------------------------------===//