main: remove -no-debug flag

The -no-debug flag controls whether to emit DWARF debug information.
However, instead of limiting debug information altogether, I think it's
better to strip it off at the end if it isn't needed. For several
reasons:

  * Some parts of the compiler now rely on the presence of debug
    information for proper diagnostics.
  * It works better with the cache: there is no distinction between
    debug and no-debug builds.
  * It makes it easier (or possible at all) to enable debug information
    in the wasi-libc library without big downsides.

I'm doing this in a separate commit so this can be reverted if needed.
This commit is contained in:
Ayke van Laethem
2021-07-12 14:25:59 +02:00
parent 2930c44bfc
commit a3ee85890d
9 changed files with 95 additions and 131 deletions
-1
View File
@@ -100,7 +100,6 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
AutomaticStackSize: config.AutomaticStackSize(), AutomaticStackSize: config.AutomaticStackSize(),
DefaultStackSize: config.Target.DefaultStackSize, DefaultStackSize: config.Target.DefaultStackSize,
NeedsStackObjects: config.NeedsStackObjects(), NeedsStackObjects: config.NeedsStackObjects(),
Debug: config.EmitDWARF(),
LLVMFeatures: config.LLVMFeatures(), LLVMFeatures: config.LLVMFeatures(),
} }
+1 -8
View File
@@ -209,9 +209,8 @@ func (c *Config) CFlags() []string {
cflags = append(cflags, "-nostdlibinc", "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(root, "lib", "picolibc", "newlib", "libc", "include")) cflags = append(cflags, "-nostdlibinc", "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(root, "lib", "picolibc", "newlib", "libc", "include"))
cflags = append(cflags, "-I"+filepath.Join(root, "lib/picolibc-include")) cflags = append(cflags, "-I"+filepath.Join(root, "lib/picolibc-include"))
} }
if c.EmitDWARF() { // Always emit debug information. It is optionally stripped at link time.
cflags = append(cflags, "-g") cflags = append(cflags, "-g")
}
return cflags return cflags
} }
@@ -250,12 +249,6 @@ func (c *Config) VerifyIR() bool {
return c.Options.VerifyIR return c.Options.VerifyIR
} }
// EmitDWARF returns whether to add debug symbols to the IR, for debugging with
// GDB and similar.
func (c *Config) EmitDWARF() bool {
return c.Options.EmitDWARF
}
// Debug returns whether debug (DWARF) information should be retained by the // Debug returns whether debug (DWARF) information should be retained by the
// linker. The default varies by target but can be controlled with the -debug // linker. The default varies by target but can be controlled with the -debug
// command line flag. // command line flag.
-1
View File
@@ -29,7 +29,6 @@ type Options struct {
DumpSSA bool DumpSSA bool
VerifyIR bool VerifyIR bool
PrintCommands func(cmd string, args ...string) PrintCommands func(cmd string, args ...string)
EmitDWARF bool
Debug string Debug string
PrintSizes string PrintSizes string
PrintAllocs *regexp.Regexp // regexp string PrintAllocs *regexp.Regexp // regexp string
+2 -16
View File
@@ -58,7 +58,6 @@ type Config struct {
AutomaticStackSize bool AutomaticStackSize bool
DefaultStackSize uint64 DefaultStackSize uint64
NeedsStackObjects bool NeedsStackObjects bool
Debug bool // Whether to emit debug information in the LLVM module.
LLVMFeatures string LLVMFeatures string
} }
@@ -103,9 +102,7 @@ func newCompilerContext(moduleName string, machine llvm.TargetMachine, config *C
c.mod = c.ctx.NewModule(moduleName) c.mod = c.ctx.NewModule(moduleName)
c.mod.SetTarget(config.Triple) c.mod.SetTarget(config.Triple)
c.mod.SetDataLayout(c.targetData.String()) c.mod.SetDataLayout(c.targetData.String())
if c.Debug {
c.dibuilder = llvm.NewDIBuilder(c.mod) c.dibuilder = llvm.NewDIBuilder(c.mod)
}
c.uintptrType = c.ctx.IntType(c.targetData.PointerSize() * 8) c.uintptrType = c.ctx.IntType(c.targetData.PointerSize() * 8)
if c.targetData.PointerSize() <= 4 { if c.targetData.PointerSize() <= 4 {
@@ -263,7 +260,6 @@ func CompilePackage(moduleName string, pkg *loader.Package, ssaPkg *ssa.Package,
ssaPkg.Build() ssaPkg.Build()
// Initialize debug information. // Initialize debug information.
if c.Debug {
c.cu = c.dibuilder.CreateCompileUnit(llvm.DICompileUnit{ c.cu = c.dibuilder.CreateCompileUnit(llvm.DICompileUnit{
Language: 0xb, // DW_LANG_C99 (0xc, off-by-one?) Language: 0xb, // DW_LANG_C99 (0xc, off-by-one?)
File: "<unknown>", File: "<unknown>",
@@ -271,7 +267,6 @@ func CompilePackage(moduleName string, pkg *loader.Package, ssaPkg *ssa.Package,
Producer: "TinyGo", Producer: "TinyGo",
Optimized: true, Optimized: true,
}) })
}
// Load comments such as //go:extern on globals. // Load comments such as //go:extern on globals.
c.loadASTComments(pkg) c.loadASTComments(pkg)
@@ -286,7 +281,6 @@ func CompilePackage(moduleName string, pkg *loader.Package, ssaPkg *ssa.Package,
c.createPackage(irbuilder, ssaPkg) c.createPackage(irbuilder, ssaPkg)
// see: https://reviews.llvm.org/D18355 // see: https://reviews.llvm.org/D18355
if c.Debug {
c.mod.AddNamedMetadataOperand("llvm.module.flags", c.mod.AddNamedMetadataOperand("llvm.module.flags",
c.ctx.MDNode([]llvm.Metadata{ c.ctx.MDNode([]llvm.Metadata{
llvm.ConstInt(c.ctx.Int32Type(), 1, false).ConstantAsMetadata(), // Error on mismatch llvm.ConstInt(c.ctx.Int32Type(), 1, false).ConstantAsMetadata(), // Error on mismatch
@@ -302,7 +296,6 @@ func CompilePackage(moduleName string, pkg *loader.Package, ssaPkg *ssa.Package,
}), }),
) )
c.dibuilder.Finalize() c.dibuilder.Finalize()
}
return c.mod, c.diagnostics return c.mod, c.diagnostics
} }
@@ -812,8 +805,7 @@ func (b *builder) createFunction() {
b.llvmFn.AddFunctionAttr(noinline) b.llvmFn.AddFunctionAttr(noinline)
} }
// Add debug info, if needed. // Add debug info.
if b.Debug {
if b.fn.Synthetic == "package initializer" { if b.fn.Synthetic == "package initializer" {
// Package initializers have no debug info. Create some fake debug // Package initializers have no debug info. Create some fake debug
// info to at least have *something*. // info to at least have *something*.
@@ -825,7 +817,6 @@ func (b *builder) createFunction() {
} }
pos := b.program.Fset.Position(b.fn.Pos()) pos := b.program.Fset.Position(b.fn.Pos())
b.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), b.difunc, llvm.Metadata{}) b.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), b.difunc, llvm.Metadata{})
}
// Pre-create all basic blocks in the function. // Pre-create all basic blocks in the function.
for _, block := range b.fn.DomPreorder() { for _, block := range b.fn.DomPreorder() {
@@ -850,7 +841,7 @@ func (b *builder) createFunction() {
b.locals[param] = b.collapseFormalParam(llvmType, fields) b.locals[param] = b.collapseFormalParam(llvmType, fields)
// Add debug information to this parameter (if available) // Add debug information to this parameter (if available)
if b.Debug && b.fn.Syntax() != nil { if b.fn.Syntax() != nil {
dbgParam := b.getLocalVariable(param.Object().(*types.Var)) dbgParam := b.getLocalVariable(param.Object().(*types.Var))
loc := b.GetCurrentDebugLocation() loc := b.GetCurrentDebugLocation()
if len(fields) == 1 { if len(fields) == 1 {
@@ -910,9 +901,6 @@ func (b *builder) createFunction() {
b.currentBlock = block b.currentBlock = block
for _, instr := range block.Instrs { for _, instr := range block.Instrs {
if instr, ok := instr.(*ssa.DebugRef); ok { if instr, ok := instr.(*ssa.DebugRef); ok {
if !b.Debug {
continue
}
object := instr.Object() object := instr.Object()
variable, ok := object.(*types.Var) variable, ok := object.(*types.Var)
if !ok { if !ok {
@@ -1029,10 +1017,8 @@ func getPos(val posser) token.Pos {
// createInstruction builds the LLVM IR equivalent instructions for the // createInstruction builds the LLVM IR equivalent instructions for the
// particular Go SSA instruction. // particular Go SSA instruction.
func (b *builder) createInstruction(instr ssa.Instruction) { func (b *builder) createInstruction(instr ssa.Instruction) {
if b.Debug {
pos := b.program.Fset.Position(getPos(instr)) pos := b.program.Fset.Position(getPos(instr))
b.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), b.difunc, llvm.Metadata{}) b.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), b.difunc, llvm.Metadata{})
}
switch instr := instr.(type) { switch instr := instr.(type) {
case ssa.Value: case ssa.Value:
+2 -4
View File
@@ -182,7 +182,7 @@ func (c *compilerContext) createGoroutineStartWrapper(fn llvm.Value, prefix stri
entry := c.ctx.AddBasicBlock(wrapper, "entry") entry := c.ctx.AddBasicBlock(wrapper, "entry")
builder.SetInsertPointAtEnd(entry) builder.SetInsertPointAtEnd(entry)
if c.Debug { // Add debug information.
pos := c.program.Fset.Position(pos) pos := c.program.Fset.Position(pos)
diFuncType := c.dibuilder.CreateSubroutineType(llvm.DISubroutineType{ diFuncType := c.dibuilder.CreateSubroutineType(llvm.DISubroutineType{
File: c.getDIFile(pos.Filename), File: c.getDIFile(pos.Filename),
@@ -202,7 +202,6 @@ func (c *compilerContext) createGoroutineStartWrapper(fn llvm.Value, prefix stri
}) })
wrapper.SetSubprogram(difunc) wrapper.SetSubprogram(difunc)
builder.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), difunc, llvm.Metadata{}) builder.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), difunc, llvm.Metadata{})
}
// Create the list of params for the call. // Create the list of params for the call.
paramTypes := fn.Type().ElementType().ParamTypes() paramTypes := fn.Type().ElementType().ParamTypes()
@@ -246,7 +245,7 @@ func (c *compilerContext) createGoroutineStartWrapper(fn llvm.Value, prefix stri
entry := c.ctx.AddBasicBlock(wrapper, "entry") entry := c.ctx.AddBasicBlock(wrapper, "entry")
builder.SetInsertPointAtEnd(entry) builder.SetInsertPointAtEnd(entry)
if c.Debug { // Add debug information.
pos := c.program.Fset.Position(pos) pos := c.program.Fset.Position(pos)
diFuncType := c.dibuilder.CreateSubroutineType(llvm.DISubroutineType{ diFuncType := c.dibuilder.CreateSubroutineType(llvm.DISubroutineType{
File: c.getDIFile(pos.Filename), File: c.getDIFile(pos.Filename),
@@ -266,7 +265,6 @@ func (c *compilerContext) createGoroutineStartWrapper(fn llvm.Value, prefix stri
}) })
wrapper.SetSubprogram(difunc) wrapper.SetSubprogram(difunc)
builder.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), difunc, llvm.Metadata{}) builder.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), difunc, llvm.Metadata{})
}
// Get the list of parameters, with the extra parameters at the end. // Get the list of parameters, with the extra parameters at the end.
paramTypes := fn.Type().ElementType().ParamTypes() paramTypes := fn.Type().ElementType().ParamTypes()
+1 -3
View File
@@ -501,12 +501,10 @@ func (c *compilerContext) getInterfaceInvokeWrapper(fn *ssa.Function, llvmFn llv
} }
defer b.Builder.Dispose() defer b.Builder.Dispose()
// add debug info if needed // add debug info
if c.Debug {
pos := c.program.Fset.Position(fn.Pos()) pos := c.program.Fset.Position(fn.Pos())
difunc := c.attachDebugInfoRaw(fn, wrapper, "$invoke", pos.Filename, pos.Line) difunc := c.attachDebugInfoRaw(fn, wrapper, "$invoke", pos.Filename, pos.Line)
b.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), difunc, llvm.Metadata{}) b.SetCurrentDebugLocation(uint(pos.Line), uint(pos.Column), difunc, llvm.Metadata{})
}
// set up IR builder // set up IR builder
block := b.ctx.AddBasicBlock(wrapper, "entry") block := b.ctx.AddBasicBlock(wrapper, "entry")
-2
View File
@@ -52,7 +52,6 @@ func (b *builder) createInterruptGlobal(instr *ssa.CallCommon) (llvm.Value, erro
global.SetInitializer(initializer) global.SetInitializer(initializer)
// Add debug info to the interrupt global. // Add debug info to the interrupt global.
if b.Debug {
pos := b.program.Fset.Position(instr.Pos()) pos := b.program.Fset.Position(instr.Pos())
diglobal := b.dibuilder.CreateGlobalVariableExpression(b.getDIFile(pos.Filename), llvm.DIGlobalVariableExpression{ diglobal := b.dibuilder.CreateGlobalVariableExpression(b.getDIFile(pos.Filename), llvm.DIGlobalVariableExpression{
Name: "interrupt" + strconv.FormatInt(id.Int64(), 10), Name: "interrupt" + strconv.FormatInt(id.Int64(), 10),
@@ -64,7 +63,6 @@ func (b *builder) createInterruptGlobal(instr *ssa.CallCommon) (llvm.Value, erro
LocalToUnit: false, LocalToUnit: false,
}) })
global.AddMetadata(0, diglobal) global.AddMetadata(0, diglobal)
}
// Create the runtime/interrupt.Interrupt type. It is a struct with a single // Create the runtime/interrupt.Interrupt type. It is a struct with a single
// member of type int. // member of type int.
+1 -1
View File
@@ -386,7 +386,7 @@ func (c *compilerContext) getGlobal(g *ssa.Global) llvm.Value {
llvmGlobal.SetAlignment(alignment) llvmGlobal.SetAlignment(alignment)
} }
if c.Debug && !info.extern { if !info.extern {
// Add debug info. // Add debug info.
pos := c.program.Fset.Position(g.Pos()) pos := c.program.Fset.Position(g.Pos())
diglobal := c.dibuilder.CreateGlobalVariableExpression(c.difiles[pos.Filename], llvm.DIGlobalVariableExpression{ diglobal := c.dibuilder.CreateGlobalVariableExpression(c.difiles[pos.Filename], llvm.DIGlobalVariableExpression{
-7
View File
@@ -1020,7 +1020,6 @@ func main() {
printAllocsString := flag.String("print-allocs", "", "regular expression of functions for which heap allocations should be printed") printAllocsString := flag.String("print-allocs", "", "regular expression of functions for which heap allocations should be printed")
printCommands := flag.Bool("x", false, "Print commands") printCommands := flag.Bool("x", false, "Print commands")
debug := flag.String("debug", "auto", "remove debug information (auto, true, false)") debug := flag.String("debug", "auto", "remove debug information (auto, true, false)")
nodebug := flag.Bool("no-debug", false, "disable DWARF debug symbol generation")
ocdCommandsString := flag.String("ocd-commands", "", "OpenOCD commands, overriding target spec (can specify multiple separated by commas)") ocdCommandsString := flag.String("ocd-commands", "", "OpenOCD commands, overriding target spec (can specify multiple separated by commas)")
ocdOutput := flag.Bool("ocd-output", false, "print OCD daemon output during debug") ocdOutput := flag.Bool("ocd-output", false, "print OCD daemon output during debug")
port := flag.String("port", "", "flash port (can specify multiple candidates separated by commas)") port := flag.String("port", "", "flash port (can specify multiple candidates separated by commas)")
@@ -1087,7 +1086,6 @@ func main() {
PrintIR: *printIR, PrintIR: *printIR,
DumpSSA: *dumpSSA, DumpSSA: *dumpSSA,
VerifyIR: *verifyIR, VerifyIR: *verifyIR,
EmitDWARF: !*nodebug,
Debug: *debug, Debug: *debug,
PrintSizes: *printSize, PrintSizes: *printSize,
PrintStacks: *printStacks, PrintStacks: *printStacks,
@@ -1175,11 +1173,6 @@ func main() {
err := Flash(pkgName, *port, options) err := Flash(pkgName, *port, options)
handleCompilerError(err) handleCompilerError(err)
} else { } else {
if !options.EmitDWARF {
fmt.Fprintln(os.Stderr, "Debug disabled while running gdb?")
usage()
os.Exit(1)
}
err := FlashGDB(pkgName, *ocdOutput, options) err := FlashGDB(pkgName, *ocdOutput, options)
handleCompilerError(err) handleCompilerError(err)
} }