Index: include/llvm/MC/MCAsmInfo.h =================================================================== --- include/llvm/MC/MCAsmInfo.h +++ include/llvm/MC/MCAsmInfo.h @@ -165,7 +165,8 @@ const char *ZeroDirective; /// This directive allows emission of an ascii string with the standard C - /// escape characters embedded into it. Defaults to "\t.ascii\t" + /// escape characters embedded into it. If a target doesn't support this, it + /// can be set to null. Defaults to "\t.ascii\t" const char *AsciiDirective; /// If not null, this allows for special handling of zero terminated strings Index: include/llvm/MC/MCStreamer.h =================================================================== --- include/llvm/MC/MCStreamer.h +++ include/llvm/MC/MCStreamer.h @@ -95,6 +95,17 @@ virtual void prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS, const MCInst &Inst, const MCSubtargetInfo &STI); + virtual void emitDwarfFileDirective(StringRef Directive); + + /// Update streamer for a new active section. + /// + /// This is called by PopSection and SwitchSection, if the current + /// section changes. + virtual void changeSection(const MCSection *CurSection, MCSection *Section, + const MCExpr *SubSection, raw_ostream &OS); + + virtual void emitValue(const MCExpr *Value); + virtual void finish(); }; Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -701,6 +701,13 @@ OutStreamer->EmitLabel(DeadBlockSyms[i]); } + // Emit pre-function debug and/or EH information. + for (const HandlerInfo &HI : Handlers) { + NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName, + HI.TimerGroupDescription, TimePassesIsEnabled); + HI.Handler->beginFunction(MF); + } + if (CurrentFnBegin) { if (MAI->useAssignmentForEHBegin()) { MCSymbol *CurPos = OutContext.createTempSymbol(); @@ -712,13 +719,6 @@ } } - // Emit pre-function debug and/or EH information. - for (const HandlerInfo &HI : Handlers) { - NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName, - HI.TimerGroupDescription, TimePassesIsEnabled); - HI.Handler->beginFunction(MF); - } - // Emit the prologue data. if (F->hasPrologueData()) EmitGlobalConstant(F->getParent()->getDataLayout(), F->getPrologueData()); Index: lib/MC/MCAsmStreamer.cpp =================================================================== --- lib/MC/MCAsmStreamer.cpp +++ lib/MC/MCAsmStreamer.cpp @@ -406,9 +406,13 @@ void MCAsmStreamer::ChangeSection(MCSection *Section, const MCExpr *Subsection) { assert(Section && "Cannot switch to a null section!"); - Section->PrintSwitchToSection( - *MAI, getContext().getObjectFileInfo()->getTargetTriple(), OS, - Subsection); + if (MCTargetStreamer *TS = getTargetStreamer()) { + TS->changeSection(getCurrentSectionOnly(), Section, Subsection, OS); + } else { + Section->PrintSwitchToSection( + *MAI, getContext().getObjectFileInfo()->getTargetTriple(), OS, + Subsection); + } } void MCAsmStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) { @@ -773,10 +777,15 @@ "Cannot emit contents before setting section!"); if (Data.empty()) return; - if (Data.size() == 1) { - OS << MAI->getData8bitsDirective(); - OS << (unsigned)(unsigned char)Data[0]; - EmitEOL(); + // If only single byte is provided or no ascii or asciz directives is + // supported, emit as vector of 8bits data. + if (Data.size() == 1 || + !(MAI->getAscizDirective() || MAI->getAsciiDirective())) { + const char *Directive = MAI->getData8bitsDirective(); + for (const unsigned char C : Data.bytes()) { + OS << Directive << (unsigned)C; + EmitEOL(); + } return; } @@ -861,8 +870,12 @@ assert(Directive && "Invalid size for machine code value!"); OS << Directive; - Value->print(OS, MAI); - EmitEOL(); + if (MCTargetStreamer *TS = getTargetStreamer()) { + TS->emitValue(Value); + } else { + Value->print(OS, MAI); + EmitEOL(); + } } void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) { @@ -1074,13 +1087,19 @@ } } - OS << "\t.file\t" << FileNo << ' '; + SmallString<128> Str; + raw_svector_ostream OS1(Str); + OS1 << "\t.file\t" << FileNo << ' '; if (!Directory.empty()) { - PrintQuotedString(Directory, OS); - OS << ' '; + PrintQuotedString(Directory, OS1); + OS1 << ' '; + } + PrintQuotedString(Filename, OS1); + if (MCTargetStreamer *TS = getTargetStreamer()) { + TS->emitDwarfFileDirective(OS1.str()); + } else { + EmitRawText(OS1.str()); } - PrintQuotedString(Filename, OS); - EmitEOL(); return FileNo; } Index: lib/MC/MCStreamer.cpp =================================================================== --- lib/MC/MCStreamer.cpp +++ lib/MC/MCStreamer.cpp @@ -49,6 +49,28 @@ void MCTargetStreamer::finish() {} +void MCTargetStreamer::changeSection(const MCSection *CurSection, + MCSection *Section, + const MCExpr *Subsection, + raw_ostream &OS) { + Section->PrintSwitchToSection( + *Streamer.getContext().getAsmInfo(), + Streamer.getContext().getObjectFileInfo()->getTargetTriple(), OS, + Subsection); +} + +void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) { + Streamer.EmitRawText(Directive); +} + +void MCTargetStreamer::emitValue(const MCExpr *Value) { + SmallString<128> Str; + raw_svector_ostream OS(Str); + + Value->print(OS, Streamer.getContext().getAsmInfo()); + Streamer.EmitRawText(OS.str()); +} + void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {} MCStreamer::MCStreamer(MCContext &Ctx) Index: test/CodeGen/Mips/mips16ex.ll =================================================================== --- test/CodeGen/Mips/mips16ex.ll +++ test/CodeGen/Mips/mips16ex.ll @@ -1,10 +1,10 @@ ; RUN: llc -march=mipsel -mattr=mips16 -relocation-model=pic -O3 < %s | FileCheck %s -check-prefix=16 ;16: main: -;16-NEXT: [[TMP:.*]]: -;16-NEXT: $func_begin0 = ([[TMP]]) ;16-NEXT: .cfi_startproc ;16-NEXT: .cfi_personality +;16: [[TMP:.*]]: +;16-NEXT: $func_begin0 = ([[TMP]]) @.str = private unnamed_addr constant [7 x i8] c"hello\0A\00", align 1 @_ZTIi = external constant i8* @.str1 = private unnamed_addr constant [15 x i8] c"exception %i \0A\00", align 1 Index: test/CodeGen/PowerPC/empty-functions.ll =================================================================== --- test/CodeGen/PowerPC/empty-functions.ll +++ test/CodeGen/PowerPC/empty-functions.ll @@ -17,8 +17,8 @@ ; An empty function is perfectly fine on ELF. ; LINUX-NO-FP: func: -; LINUX-NO-FP-NEXT: {{^}}.L[[BEGIN:.*]]:{{$}} ; LINUX-NO-FP-NEXT: .cfi_startproc +; LINUX-NO-FP-NEXT: {{^}}.L[[BEGIN:.*]]:{{$}} ; LINUX-NO-FP-NEXT: {{^}}# ; LINUX-NO-FP-NEXT: {{^}}.L[[END:.*]]:{{$}} ; LINUX-NO-FP-NEXT: .size func, .L[[END]]-.L[[BEGIN]] @@ -26,8 +26,8 @@ ; A cfi directive cannot point to the end of a function. ; LINUX-FP: func: -; LINUX-FP-NEXT: {{^}}.L[[BEGIN:.*]]:{{$}} ; LINUX-FP-NEXT: .cfi_startproc +; LINUX-FP-NEXT: {{^}}.L[[BEGIN:.*]]:{{$}} ; LINUX-FP-NEXT: {{^}}# ; LINUX-FP-NEXT: stwu 1, -16(1) ; LINUX-FP-NEXT: stw 31, 12(1) Index: test/CodeGen/X86/debug-nodebug-crash.ll =================================================================== --- test/CodeGen/X86/debug-nodebug-crash.ll +++ test/CodeGen/X86/debug-nodebug-crash.ll @@ -8,10 +8,10 @@ ; reasonable output, preserving function labels and a DBG_VALUE comment. ; ; CHECK-LABEL: foo: -; CHECK-NEXT: Lfunc_begin0: +; CHECK: Lfunc_begin0: ; CHECK: Lfunc_end0: ; CHECK-LABEL: bar: -; CHECK-NEXT: Lfunc_begin1: +; CHECK: Lfunc_begin1: ; CHECK: #DEBUG_VALUE: foo:x <- ; CHECK: Lfunc_end1: Index: test/CodeGen/X86/eh-unknown.ll =================================================================== --- test/CodeGen/X86/eh-unknown.ll +++ test/CodeGen/X86/eh-unknown.ll @@ -15,8 +15,8 @@ } ; CHECK-LABEL: use_unknown_ehpersonality: -; CHECK: .Lfunc_begin0: ; CHECK: .seh_handler __unknown_ehpersonality, @unwind, @except +; CHECK: .Lfunc_begin0: ; CHECK: callq throwit ; CHECK: .Lfunc_end0: ; CHECK: .seh_handlerdata Index: test/CodeGen/X86/patchpoint-invoke.ll =================================================================== --- test/CodeGen/X86/patchpoint-invoke.ll +++ test/CodeGen/X86/patchpoint-invoke.ll @@ -5,9 +5,9 @@ define i64 @patchpoint_invoke(i64 %p1, i64 %p2) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { entry: ; CHECK-LABEL: patchpoint_invoke: -; CHECK-NEXT: [[FUNC_BEGIN:.L.*]]: ; CHECK-NEXT: .cfi_startproc ; CHECK: .cfi_lsda 3, [[EXCEPTION_LABEL:.L[^ ]*]] +; CHECK-NEXT: [[FUNC_BEGIN:.L.*]]: ; CHECK: pushq %rbp ; Unfortunately, hardcode the name of the label that begins the patchpoint: Index: test/CodeGen/X86/wineh-coreclr.ll =================================================================== --- test/CodeGen/X86/wineh-coreclr.ll +++ test/CodeGen/X86/wineh-coreclr.ll @@ -28,7 +28,7 @@ ; } ; ; CHECK-LABEL: test1: # @test1 -; CHECK-NEXT: [[test1_begin:.*func_begin.*]]: +; CHECK: [[test1_begin:.*func_begin.*]]: define void @test1() personality i8* bitcast (void ()* @ProcessCLRException to i8*) { entry: ; CHECK: # %entry @@ -307,7 +307,7 @@ unreachable } ; CHECK-LABEL: test2: # @test2 -; CHECK-NEXT: [[test2_begin:.*func_begin.*]]: +; CHECK: [[test2_begin:.*func_begin.*]]: ; CHECK: .seh_endprologue ; CHECK: [[test2_before_f1:.+]]: ; CHECK-NEXT: movl $1, %ecx @@ -440,7 +440,7 @@ ; } ; ; CHECK-LABEL: test3: # @test3 -; CHECK-NEXT: [[test3_begin:.*func_begin.*]]: +; CHECK: [[test3_begin:.*func_begin.*]]: define void @test3() personality i8* bitcast (void ()* @ProcessCLRException to i8*) { entry: ; CHECK: .seh_endprologue Index: test/CodeGen/XCore/exception.ll =================================================================== --- test/CodeGen/XCore/exception.ll +++ test/CodeGen/XCore/exception.ll @@ -40,10 +40,10 @@ } ; CHECK-LABEL: fn_catch: -; CHECK-NEXT: [[START:.L[a-zA-Z0-9_]+]] ; CHECK: .cfi_startproc ; CHECK: .cfi_personality 0, __gxx_personality_v0 ; CHECK: .cfi_lsda 0, [[LSDA:.L[a-zA-Z0-9_]+]] +; CHECK-NEXT: [[START:.L[a-zA-Z0-9_]+]] ; CHECK: entsp 4 ; CHECK: .cfi_def_cfa_offset 16 ; CHECK: .cfi_offset 15, 0 Index: test/DebugInfo/COFF/inlining-header.ll =================================================================== --- test/DebugInfo/COFF/inlining-header.ll +++ test/DebugInfo/COFF/inlining-header.ll @@ -24,8 +24,8 @@ ; } ; ASM: _main: # @main -; ASM: Lfunc_begin0: ; ASM: .cv_func_id 0 +; ASM: Lfunc_begin0: ; ASM: # BB#0: # %entry ; ASM: .cv_file 1 "D:\\src\\llvm\\build\\t.cpp" ; ASM: .cv_loc 0 1 9 5 is_stmt 0 # t.cpp:9:5 Index: test/DebugInfo/COFF/multifile.ll =================================================================== --- test/DebugInfo/COFF/multifile.ll +++ test/DebugInfo/COFF/multifile.ll @@ -103,9 +103,9 @@ ; OBJ32-NEXT: ] ; X64-LABEL: f: -; X64-NEXT: .L{{.*}}:{{$}} ; X64: .cv_file 1 "D:\\input.c" "70B51F534D80639D033AE92C6A856AF6" 1 ; X64: .cv_loc 0 1 3 0 is_stmt 0 # input.c:3:0 +; X64-NEXT: .L{{.*}}:{{$}} ; X64: # BB ; X64: subq $40, %rsp ; X64: .cv_file 2 "D:\\one.c" "70B51F534D80639D033AE92C6A856AF6" 1 Index: test/DebugInfo/COFF/multifunction.ll =================================================================== --- test/DebugInfo/COFF/multifunction.ll +++ test/DebugInfo/COFF/multifunction.ll @@ -284,9 +284,9 @@ ; X64-LABEL: x: -; X64-NEXT: .L{{.*}}: ; X64: .cv_file 1 "D:\\source.c" ; X64: .cv_loc 0 1 3 0 is_stmt 0 # source.c:3:0 +; X64-NEXT: .L{{.*}}: ; X64: # BB ; X64: subq $40, %rsp ; X64: .cv_loc 0 1 4 42 # source.c:4:42 @@ -297,8 +297,8 @@ ; X64: [[END_OF_X:.?Lfunc_end.*]]: ; ; X64-LABEL: y: -; X64-NEXT: .L{{.*}}: ; X64: .cv_loc 1 1 7 0 # source.c:7:0 +; X64-NEXT: .L{{.*}}: ; X64: # BB ; X64: subq $40, %rsp ; X64: .cv_loc 1 1 8 52 # source.c:8:52 @@ -309,8 +309,8 @@ ; X64: [[END_OF_Y:.?Lfunc_end.*]]: ; ; X64-LABEL: f: -; X64-NEXT: .L{{.*}}: ; X64: .cv_loc 2 1 11 0 # source.c:11:0 +; X64-NEXT: .L{{.*}}: ; X64: # BB ; X64: subq $40, %rsp ; X64: .cv_loc 2 1 12 62 # source.c:12:62 Index: test/DebugInfo/COFF/simple.ll =================================================================== --- test/DebugInfo/COFF/simple.ll +++ test/DebugInfo/COFF/simple.ll @@ -128,9 +128,9 @@ ; OBJ32-NEXT: ] ; X64-LABEL: f: -; X64-NEXT: .L{{.*}}:{{$}} ; X64: .cv_file 1 "D:\\test.c" "F310AB26998CA831CBDF169E4EECACFA" 1 ; X64: .cv_loc 0 1 3 0 is_stmt 0 # test.c:3:0 +; X64-NEXT: .L{{.*}}:{{$}} ; X64: # BB ; X64: subq $40, %rsp ; X64: .cv_loc 0 1 4 2 # test.c:4:2