gollvm: minor enhancements to capture-fcn-attributes.go
Update the capture-fcn-attributes tool to better handle quirks
in clang with respect to how the -mcpu=... and -march=... command
line options are handled (there is some inconsistency there). In
addition, trim the output of "clang --version" to insure that
we're not accidentally sharing github token info.
Change-Id: Iaabb248f57886b0f945052db5e6398ad8dd43072
Reviewed-on: https://go-review.googlesource.com/c/gollvm/+/271687
Trust: Than McIntosh <thanm@google.com>
Trust: eric fang <eric.fang@arm.com>
Reviewed-by: eric fang <eric.fang@arm.com>
diff --git a/tools/capture-fcn-attributes.go b/tools/capture-fcn-attributes.go
index fb65466..545d7cd 100644
--- a/tools/capture-fcn-attributes.go
+++ b/tools/capture-fcn-attributes.go
@@ -273,10 +273,76 @@
}
}
+// enumerateAttributesForCPU invokes clang to capture the attribute
+// set for a given CPU within a given target, sending the results to
+// the specified channel.
+func enumerateAttributesForCPU(triple string, tdir string, cpu string, tf string, rchan chan result) {
+
+ //
+ // Confusingly, for some targets "-mcpu=XXX" is required (use of
+ // -march=XXX will be rejected), whereas for other targets if you
+ // use -mcpu=XXX instead of -march=XXX the compile will succeed,
+ // but you'll get a warning message of the form "warning: argument
+ // unused during compilation: '-mcpu=XXX'". To work around this,
+ // try first -mcpu and then fall back on -march if the warning
+ // is generated for -mcpu.
+ //
+ attempts := []string{"cpu", "arch"}
+ lloutfile := filepath.Join(tdir, fmt.Sprintf("%s.ll", cpu))
+ for _, cpuarch := range attempts {
+ clargs := []string{"-emit-llvm", "-S", "-o", lloutfile,
+ "-O3", "-Xclang", "-disable-llvm-passes", tf}
+ if triple != "" {
+ clargs = append(clargs, fmt.Sprintf("--target=%s", triple))
+ }
+ if cpu != "" {
+ clargs = append(clargs, fmt.Sprintf("-m%s=%s", cpuarch, cpu))
+ }
+ emitClangCmdLine(tdir, cpu, clargs)
+ cmd := exec.Command("clang", clargs...)
+ output, cerr := cmd.CombinedOutput()
+ if cerr != nil {
+ if *verbflag > 0 || triple == "" {
+ warn("clang run failed: %s", output)
+ }
+ if triple == "" {
+ fatal("err = %v", cerr)
+ }
+
+ // Note the 'supported:false' (indicating that this CPU
+ // value is not viable).
+ rchan <- result{cpu: cpu, attrs: strings.Join(clargs, " "), supported: false, def: false}
+ return
+ } else {
+ // Look for "argument unused" warning.
+ warning := "argument unused during compilation: '-mcpu="
+ if strings.Contains(string(output), warning) {
+ // Move on to try -march
+ continue
+ }
+ // Sift through the output for attr set.
+ acpu, attrs := parseClangOutFile(lloutfile)
+ adef := false
+ if cpu == "" || cpu == "generic" && acpu == "generic" {
+ adef = true
+ }
+ // Send results on to the consumer.
+ rchan <- result{cpu: acpu, attrs: attrs, supported: true, def: adef}
+ return
+ }
+ }
+}
+
func enumerateAttributes(triple string, tdir string, cpus []string, tf string) []result {
verb(1, "enumerating attributes for %d cpus", len(cpus))
+ tripleTmp := filepath.Join(tdir, triple)
+ mkdirErr := os.Mkdir(tripleTmp, 0755)
+ if mkdirErr != nil {
+ fatal("unable to make tmp dir: %v", mkdirErr)
+ }
+
// First entry in the list needs to be the default CPU
ecpus := append([]string{""}, cpus...)
@@ -285,45 +351,7 @@
defer close(rchan)
for _, cpu := range ecpus {
verb(1, "enumerate for cpu %s", cpu)
-
- go func(cpu string) {
-
- // Invoke clang with proper arguments
- lloutfile := filepath.Join(tdir, fmt.Sprintf("%s.ll", cpu))
- clargs := []string{"-emit-llvm", "-S", "-o", lloutfile,
- "-O3", "-Xclang", "-disable-llvm-passes", tf}
- cpuarch := "arch"
- if triple != "" {
- clargs = append(clargs, fmt.Sprintf("--target=%s", triple))
- }
- if triple != defaultTriple {
- cpuarch = "cpu"
- }
- if cpu != "" {
- clargs = append(clargs, fmt.Sprintf("-m%s=%s", cpuarch, cpu))
- }
- emitClangCmdLine(tdir, cpu, clargs)
- cmd := exec.Command("clang", clargs...)
- output, cerr := cmd.CombinedOutput()
- if cerr != nil {
- if triple == "" {
- warn("clang run failed: %s", output)
- fatal("err = %v", cerr)
- }
- // Note the 'supported:false' (indicating that this CPU
- // value is not viable).
- rchan <- result{cpu: cpu, attrs: strings.Join(clargs, " "), supported: false, def: false}
- } else {
- // Sift through the output for attr set.
- acpu, attrs := parseClangOutFile(lloutfile)
- adef := false
- if cpu == "" || cpu == "generic" && acpu == "generic" {
- adef = true
- }
- // Send results on to the consume.
- rchan <- result{cpu: acpu, attrs: attrs, supported: true, def: adef}
- }
- }(cpu)
+ go enumerateAttributesForCPU(triple, tripleTmp, cpu, tf, rchan)
}
// Read raw results.
@@ -464,7 +492,12 @@
warn("clang run failed: %s", output)
fatal("err = %v", cerr)
}
- sl := strings.Split(string(output), "\n")
+ // clang --version includes full output from git remote -v, which
+ // can include github access token (we definitely don't want to
+ // share that); strip it out if we see something like that.
+ m := regexp.MustCompile(`://(\S+:\S+)@`)
+ trimmed := m.ReplaceAllString(string(output), "://")
+ sl := strings.Split(trimmed, "\n")
bw.WriteString("// ")
bw.WriteString(sl[0])
bw.WriteString("\n//\n")
@@ -557,7 +590,7 @@
fmt.Fprintf(bw, "// triple:")
for i := 0; i < len(res.triples); i++ {
trip := res.triples[i]
- if i != len(res.triples) - 1 {
+ if i != len(res.triples)-1 {
fmt.Fprintf(bw, " %s,", trip)
} else {
fmt.Fprintf(bw, " %s", trip)