blob: 0679d13865f2420e5befb1e74bbc21ea01664e1a [file] [log] [blame]
Yi Kongd5954a22022-01-26 17:36:26 +08001// Copyright 2022 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17import (
Colin Crosse00614e2024-02-09 12:19:55 -080018 "runtime"
Liz Kammer8c8e8d52022-10-31 15:53:36 -040019 "strings"
Yi Kongd5954a22022-01-26 17:36:26 +080020 "testing"
21
22 "android/soong/android"
Liz Kammer8c8e8d52022-10-31 15:53:36 -040023
Yi Kongd5954a22022-01-26 17:36:26 +080024 "github.com/google/blueprint"
25)
26
Liz Kammer8c8e8d52022-10-31 15:53:36 -040027type visitDirectDepsInterface interface {
28 VisitDirectDeps(blueprint.Module, func(dep blueprint.Module))
29}
30
31func hasDirectDep(ctx visitDirectDepsInterface, m android.Module, wantDep android.Module) bool {
32 var found bool
33 ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
34 if dep == wantDep {
35 found = true
36 }
37 })
38 return found
39}
40
Yi Kongd5954a22022-01-26 17:36:26 +080041func TestAfdoDeps(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -040042 t.Parallel()
Yi Kongd5954a22022-01-26 17:36:26 +080043 bp := `
Liz Kammer8c8e8d52022-10-31 15:53:36 -040044 cc_library_shared {
Yi Kongd5954a22022-01-26 17:36:26 +080045 name: "libTest",
Colin Cross15fa8142024-02-07 15:09:08 -080046 host_supported: true,
Liz Kammer8c8e8d52022-10-31 15:53:36 -040047 srcs: ["test.c"],
Yi Kongd5954a22022-01-26 17:36:26 +080048 static_libs: ["libFoo"],
49 afdo: true,
Colin Crossda4c89f2024-02-07 15:03:01 -080050 lto: {
51 thin: true,
52 },
Yi Kongd5954a22022-01-26 17:36:26 +080053 }
54
Liz Kammer8c8e8d52022-10-31 15:53:36 -040055 cc_library_static {
Yi Kongd5954a22022-01-26 17:36:26 +080056 name: "libFoo",
Colin Cross15fa8142024-02-07 15:09:08 -080057 host_supported: true,
Liz Kammer8c8e8d52022-10-31 15:53:36 -040058 srcs: ["foo.c"],
Yi Kongd5954a22022-01-26 17:36:26 +080059 static_libs: ["libBar"],
60 }
61
Liz Kammer8c8e8d52022-10-31 15:53:36 -040062 cc_library_static {
Yi Kongd5954a22022-01-26 17:36:26 +080063 name: "libBar",
Colin Cross15fa8142024-02-07 15:09:08 -080064 host_supported: true,
Liz Kammer8c8e8d52022-10-31 15:53:36 -040065 srcs: ["bar.c"],
Yi Kongd5954a22022-01-26 17:36:26 +080066 }
67 `
Yi Kongd5954a22022-01-26 17:36:26 +080068
69 result := android.GroupFixturePreparers(
Vinh Trancde10162023-03-09 22:07:19 -050070 PrepareForTestWithFdoProfile,
Yi Kongd5954a22022-01-26 17:36:26 +080071 prepareForCcTest,
Vinh Tran44cb78c2023-03-09 22:07:19 -050072 android.FixtureAddTextFile("afdo_profiles_package/libTest.afdo", ""),
73 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
74 variables.AfdoProfiles = []string{
75 "libTest://afdo_profiles_package:libTest_afdo",
76 }
77 }),
78 android.MockFS{
79 "afdo_profiles_package/Android.bp": []byte(`
80 fdo_profile {
81 name: "libTest_afdo",
Colin Crossda4c89f2024-02-07 15:03:01 -080082 arch: {
83 arm64: {
84 profile: "libTest.afdo",
85 },
86 },
Vinh Tran44cb78c2023-03-09 22:07:19 -050087 }
88 `),
89 }.AddToFixture(),
Yi Kongd5954a22022-01-26 17:36:26 +080090 ).RunTestWithBp(t, bp)
91
Colin Crossda4c89f2024-02-07 15:03:01 -080092 profileSampleCFlag := "-fprofile-sample-use=afdo_profiles_package/libTest.afdo"
93 uniqueInternalLinkageNamesCFlag := "-funique-internal-linkage-names"
94 afdoLtoLdFlag := "-Wl,-plugin-opt,-import-instr-limit=40"
95 noAfdoLtoLdFlag := "-Wl,-plugin-opt,-import-instr-limit=5"
Yi Kongd5954a22022-01-26 17:36:26 +080096
Vinh Tran44cb78c2023-03-09 22:07:19 -050097 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
98 libFooAfdoVariant := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest")
99 libBarAfdoVariant := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_afdo-libTest")
100
101 // Check cFlags of afdo-enabled module and the afdo-variant of its static deps
102 cFlags := libTest.Rule("cc").Args["cFlags"]
Colin Crossda4c89f2024-02-07 15:03:01 -0800103 if !strings.Contains(cFlags, profileSampleCFlag) {
104 t.Errorf("Expected 'libTest' to enable afdo profile, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
105 }
106 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
107 t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
108 }
109
110 ldFlags := libTest.Rule("ld").Args["ldFlags"]
111 if !strings.Contains(ldFlags, afdoLtoLdFlag) {
112 t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in ldflags %q", afdoLtoLdFlag, ldFlags)
Vinh Tran44cb78c2023-03-09 22:07:19 -0500113 }
114
115 cFlags = libFooAfdoVariant.Rule("cc").Args["cFlags"]
Colin Crossda4c89f2024-02-07 15:03:01 -0800116 if !strings.Contains(cFlags, profileSampleCFlag) {
117 t.Errorf("Expected 'libFooAfdoVariant' to enable afdo profile, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
118 }
119 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
120 t.Errorf("Expected 'libFooAfdoVariant' to enable afdo, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
Vinh Tran44cb78c2023-03-09 22:07:19 -0500121 }
122
123 cFlags = libBarAfdoVariant.Rule("cc").Args["cFlags"]
Colin Crossda4c89f2024-02-07 15:03:01 -0800124 if !strings.Contains(cFlags, profileSampleCFlag) {
125 t.Errorf("Expected 'libBarAfdoVariant' to enable afdo profile, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
126 }
127 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
128 t.Errorf("Expected 'libBarAfdoVariant' to enable afdo, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
Vinh Tran44cb78c2023-03-09 22:07:19 -0500129 }
130
131 // Check dependency edge from afdo-enabled module to static deps
132 if !hasDirectDep(result, libTest.Module(), libFooAfdoVariant.Module()) {
Yi Kongd5954a22022-01-26 17:36:26 +0800133 t.Errorf("libTest missing dependency on afdo variant of libFoo")
134 }
135
Vinh Tran44cb78c2023-03-09 22:07:19 -0500136 if !hasDirectDep(result, libFooAfdoVariant.Module(), libBarAfdoVariant.Module()) {
Yi Kongd5954a22022-01-26 17:36:26 +0800137 t.Errorf("libTest missing dependency on afdo variant of libBar")
138 }
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400139
Vinh Tran44cb78c2023-03-09 22:07:19 -0500140 // Verify non-afdo variant exists and doesn't contain afdo
141 libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
142 libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400143
144 cFlags = libFoo.Rule("cc").Args["cFlags"]
Colin Crossda4c89f2024-02-07 15:03:01 -0800145 if strings.Contains(cFlags, profileSampleCFlag) {
146 t.Errorf("Expected 'libFoo' to not enable afdo profile, but found %q in cflags %q", profileSampleCFlag, cFlags)
147 }
148 if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
149 t.Errorf("Expected 'libFoo' to not enable afdo, but found %q in cflags %q", profileSampleCFlag, cFlags)
Vinh Tran44cb78c2023-03-09 22:07:19 -0500150 }
151 cFlags = libBar.Rule("cc").Args["cFlags"]
Colin Crossda4c89f2024-02-07 15:03:01 -0800152 if strings.Contains(cFlags, profileSampleCFlag) {
153 t.Errorf("Expected 'libBar' to not enable afdo profile, but found %q in cflags %q", profileSampleCFlag, cFlags)
154 }
155 if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
156 t.Errorf("Expected 'libBar' to not enable afdo, but found %q in cflags %q", profileSampleCFlag, cFlags)
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400157 }
158
Vinh Tran44cb78c2023-03-09 22:07:19 -0500159 // Check dependency edges of static deps
160 if hasDirectDep(result, libTest.Module(), libFoo.Module()) {
161 t.Errorf("libTest should not depend on non-afdo variant of libFoo")
162 }
163
164 if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
165 t.Errorf("libFoo missing dependency on non-afdo variant of libBar")
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400166 }
Colin Crossda4c89f2024-02-07 15:03:01 -0800167
168 // Verify that the arm variant does not have FDO since the fdo_profile module only has a profile for arm64
169 libTest32 := result.ModuleForTests("libTest", "android_arm_armv7-a-neon_shared")
170 libFooAfdoVariant32 := result.ModuleForTests("libFoo", "android_arm_armv7-a-neon_static_afdo-libTest_lto-thin")
171 libBarAfdoVariant32 := result.ModuleForTests("libBar", "android_arm_armv7-a-neon_static_afdo-libTest_lto-thin")
172
173 cFlags = libTest32.Rule("cc").Args["cFlags"]
174 if strings.Contains(cFlags, profileSampleCFlag) {
175 t.Errorf("Expected arm32 'libTest' not to enable afdo, but found %q in cflags %q", profileSampleCFlag, cFlags)
176 }
177
178 // TODO(b/324141705): when the fdo_profile module doesn't provide a source file the dependencies don't get
179 // -funique-internal-linkage-names but the module does.
180 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
181 t.Errorf("Expected arm32 'libTest' to enable -funique-internal-linkage-names but did not find %q in cflags %q",
182 uniqueInternalLinkageNamesCFlag, cFlags)
183 }
184
185 ldFlags = libTest32.Rule("ld").Args["ldFlags"]
186 if !strings.Contains(ldFlags, noAfdoLtoLdFlag) {
187 t.Errorf("Expected arm32 'libTest' to not enable afdo, but did not find %q in ldflags %q", noAfdoLtoLdFlag, ldFlags)
188 }
189 if strings.Contains(ldFlags, afdoLtoLdFlag) {
190 t.Errorf("Expected arm32 'libTest' to not enable afdo, but found %q in ldflags %q", afdoLtoLdFlag, ldFlags)
191 }
192
193 // Check dependency edge from afdo-enabled module to static deps
194 if !hasDirectDep(result, libTest32.Module(), libFooAfdoVariant32.Module()) {
195 t.Errorf("arm32 libTest missing dependency on afdo variant of libFoo")
196 }
197
198 if !hasDirectDep(result, libFooAfdoVariant32.Module(), libBarAfdoVariant32.Module()) {
199 t.Errorf("arm32 libTest missing dependency on afdo variant of libBar")
200 }
201
202 cFlags = libFooAfdoVariant32.Rule("cc").Args["cFlags"]
203 if strings.Contains(cFlags, profileSampleCFlag) {
204 t.Errorf("Expected arm32 'libFoo' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
205 }
206 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
207 t.Errorf("Expected arm32 'libFoo' to enable afdo, but did not find %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
208 }
209 cFlags = libBarAfdoVariant32.Rule("cc").Args["cFlags"]
210 if strings.Contains(cFlags, profileSampleCFlag) {
211 t.Errorf("Expected arm32 'libBar' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
212 }
213 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
214 t.Errorf("Expected arm32 'libBar' to enable afdo, but did not find %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
215 }
216
Colin Cross15fa8142024-02-07 15:09:08 -0800217 // Verify that the host variants don't enable afdo
218 libTestHost := result.ModuleForTests("libTest", result.Config.BuildOSTarget.String()+"_shared")
219 libFooHost := result.ModuleForTests("libFoo", result.Config.BuildOSTarget.String()+"_static_lto-thin")
220 libBarHost := result.ModuleForTests("libBar", result.Config.BuildOSTarget.String()+"_static_lto-thin")
221
222 cFlags = libTestHost.Rule("cc").Args["cFlags"]
223 if strings.Contains(cFlags, profileSampleCFlag) {
224 t.Errorf("Expected host 'libTest' to not enable afdo profile, but found %q in cflags %q", profileSampleCFlag, cFlags)
225 }
226
227 if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
228 t.Errorf("Expected host 'libTest' to not enable afdo but found %q in cflags %q",
229 uniqueInternalLinkageNamesCFlag, cFlags)
230 }
231
Colin Crosse00614e2024-02-09 12:19:55 -0800232 if runtime.GOOS != "darwin" {
233 ldFlags := libTestHost.Rule("ld").Args["ldFlags"]
234 if !strings.Contains(ldFlags, noAfdoLtoLdFlag) {
235 t.Errorf("Expected host 'libTest' to not enable afdo, but did not find %q in ldflags %q", noAfdoLtoLdFlag, ldFlags)
236 }
237 if strings.Contains(ldFlags, afdoLtoLdFlag) {
238 t.Errorf("Expected host 'libTest' to not enable afdo, but found %q in ldflags %q", afdoLtoLdFlag, ldFlags)
239 }
Colin Cross15fa8142024-02-07 15:09:08 -0800240 }
241
242 // Check dependency edge from afdo-enabled module to static deps
243 if !hasDirectDep(result, libTestHost.Module(), libFooHost.Module()) {
244 t.Errorf("host libTest missing dependency on non-afdo variant of libFoo")
245 }
246
247 if !hasDirectDep(result, libFooHost.Module(), libBarHost.Module()) {
248 t.Errorf("host libTest missing dependency on non-afdo variant of libBar")
249 }
250
251 cFlags = libFooHost.Rule("cc").Args["cFlags"]
252 if strings.Contains(cFlags, profileSampleCFlag) {
253 t.Errorf("Expected host 'libFoo' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
254 }
255 if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
256 t.Errorf("Expected host 'libFoo' to not enable afdo, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
257 }
258 cFlags = libBarHost.Rule("cc").Args["cFlags"]
259 if strings.Contains(cFlags, profileSampleCFlag) {
260 t.Errorf("Expected host 'libBar' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
261 }
262 if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
263 t.Errorf("Expected host 'libBar' to not enable afdo, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
264 }
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400265}
266
267func TestAfdoEnabledOnStaticDepNoAfdo(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400268 t.Parallel()
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400269 bp := `
270 cc_library_shared {
271 name: "libTest",
272 srcs: ["foo.c"],
273 static_libs: ["libFoo"],
274 }
275
276 cc_library_static {
277 name: "libFoo",
278 srcs: ["foo.c"],
279 static_libs: ["libBar"],
280 afdo: true, // TODO(b/256670524): remove support for enabling afdo from static only libraries, this can only propagate from shared libraries/binaries
281 }
282
283 cc_library_static {
284 name: "libBar",
285 }
286 `
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400287
288 result := android.GroupFixturePreparers(
289 prepareForCcTest,
Vinh Trancde10162023-03-09 22:07:19 -0500290 PrepareForTestWithFdoProfile,
Vinh Tran44cb78c2023-03-09 22:07:19 -0500291 android.FixtureAddTextFile("toolchain/pgo-profiles/sampling/libFoo.afdo", ""),
292 android.MockFS{
293 "afdo_profiles_package/Android.bp": []byte(`
294 soong_namespace {
295 }
296 fdo_profile {
297 name: "libFoo_afdo",
298 profile: "libFoo.afdo",
299 }
300 `),
301 }.AddToFixture(),
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400302 ).RunTestWithBp(t, bp)
303
304 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared").Module()
305 libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
306 libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static").Module()
307
308 if !hasDirectDep(result, libTest, libFoo.Module()) {
Colin Crossda4c89f2024-02-07 15:03:01 -0800309 t.Errorf("libTest missing dependency on non-afdo variant of libFoo")
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400310 }
311
312 if !hasDirectDep(result, libFoo.Module(), libBar) {
Colin Crossda4c89f2024-02-07 15:03:01 -0800313 t.Errorf("libFoo missing dependency on non-afdo variant of libBar")
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400314 }
315
316 fooVariants := result.ModuleVariantsForTests("foo")
317 for _, v := range fooVariants {
318 if strings.Contains(v, "afdo-") {
319 t.Errorf("Expected no afdo variant of 'foo', got %q", v)
320 }
321 }
322
323 cFlags := libFoo.Rule("cc").Args["cFlags"]
324 if w := "-fprofile-sample-accurate"; strings.Contains(cFlags, w) {
325 t.Errorf("Expected 'foo' to not enable afdo, but found %q in cflags %q", w, cFlags)
326 }
327
328 barVariants := result.ModuleVariantsForTests("bar")
329 for _, v := range barVariants {
330 if strings.Contains(v, "afdo-") {
331 t.Errorf("Expected no afdo variant of 'bar', got %q", v)
332 }
333 }
Yi Kongd5954a22022-01-26 17:36:26 +0800334}
Vinh Tran9c6080c2022-12-05 14:55:38 -0500335
336func TestAfdoEnabledWithRuntimeDepNoAfdo(t *testing.T) {
337 bp := `
338 cc_library {
339 name: "libTest",
340 srcs: ["foo.c"],
341 runtime_libs: ["libFoo"],
342 afdo: true,
343 }
344
345 cc_library {
346 name: "libFoo",
347 }
348 `
Vinh Tran9c6080c2022-12-05 14:55:38 -0500349
350 result := android.GroupFixturePreparers(
351 prepareForCcTest,
Vinh Trancde10162023-03-09 22:07:19 -0500352 PrepareForTestWithFdoProfile,
Vinh Tran44cb78c2023-03-09 22:07:19 -0500353 android.FixtureAddTextFile("afdo_profiles_package/libTest.afdo", ""),
354 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
355 variables.AfdoProfiles = []string{
356 "libTest://afdo_profiles_package:libTest_afdo",
357 }
358 }),
359 android.MockFS{
360 "afdo_profiles_package/Android.bp": []byte(`
361 fdo_profile {
362 name: "libTest_afdo",
363 profile: "libTest.afdo",
364 }
365 `),
366 }.AddToFixture(),
Vinh Tran9c6080c2022-12-05 14:55:38 -0500367 ).RunTestWithBp(t, bp)
368
369 libFooVariants := result.ModuleVariantsForTests("libFoo")
370 for _, v := range libFooVariants {
371 if strings.Contains(v, "afdo-") {
372 t.Errorf("Expected no afdo variant of 'foo', got %q", v)
373 }
374 }
375}
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400376
377func TestAfdoEnabledWithMultiArchs(t *testing.T) {
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400378 bp := `
379 cc_library_shared {
380 name: "foo",
381 srcs: ["test.c"],
382 afdo: true,
383 compile_multilib: "both",
384 }
385`
386 result := android.GroupFixturePreparers(
Vinh Trancde10162023-03-09 22:07:19 -0500387 PrepareForTestWithFdoProfile,
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400388 prepareForCcTest,
Vinh Tran44cb78c2023-03-09 22:07:19 -0500389 android.FixtureAddTextFile("afdo_profiles_package/foo_arm.afdo", ""),
390 android.FixtureAddTextFile("afdo_profiles_package/foo_arm64.afdo", ""),
391 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
392 variables.AfdoProfiles = []string{
393 "foo://afdo_profiles_package:foo_afdo",
394 }
395 }),
396 android.MockFS{
397 "afdo_profiles_package/Android.bp": []byte(`
398 soong_namespace {
399 }
400 fdo_profile {
401 name: "foo_afdo",
402 arch: {
403 arm: {
404 profile: "foo_arm.afdo",
405 },
406 arm64: {
407 profile: "foo_arm64.afdo",
408 }
409 }
410 }
411 `),
412 }.AddToFixture(),
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400413 ).RunTestWithBp(t, bp)
414
415 fooArm := result.ModuleForTests("foo", "android_arm_armv7-a-neon_shared")
416 fooArmCFlags := fooArm.Rule("cc").Args["cFlags"]
Vinh Tran44cb78c2023-03-09 22:07:19 -0500417 if w := "-fprofile-sample-use=afdo_profiles_package/foo_arm.afdo"; !strings.Contains(fooArmCFlags, w) {
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400418 t.Errorf("Expected 'foo' to enable afdo, but did not find %q in cflags %q", w, fooArmCFlags)
419 }
420
421 fooArm64 := result.ModuleForTests("foo", "android_arm64_armv8-a_shared")
422 fooArm64CFlags := fooArm64.Rule("cc").Args["cFlags"]
Vinh Tran44cb78c2023-03-09 22:07:19 -0500423 if w := "-fprofile-sample-use=afdo_profiles_package/foo_arm64.afdo"; !strings.Contains(fooArm64CFlags, w) {
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400424 t.Errorf("Expected 'foo' to enable afdo, but did not find %q in cflags %q", w, fooArm64CFlags)
425 }
426}
427
428func TestMultipleAfdoRDeps(t *testing.T) {
429 t.Parallel()
430 bp := `
431 cc_library_shared {
432 name: "libTest",
433 srcs: ["test.c"],
434 static_libs: ["libFoo"],
435 afdo: true,
436 }
437
438 cc_library_shared {
439 name: "libBar",
440 srcs: ["bar.c"],
441 static_libs: ["libFoo"],
442 afdo: true,
443 }
444
445 cc_library_static {
446 name: "libFoo",
447 srcs: ["foo.c"],
448 }
449 `
450
451 result := android.GroupFixturePreparers(
Vinh Trancde10162023-03-09 22:07:19 -0500452 PrepareForTestWithFdoProfile,
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400453 prepareForCcTest,
Vinh Tran44cb78c2023-03-09 22:07:19 -0500454 android.FixtureAddTextFile("afdo_profiles_package/libTest.afdo", ""),
455 android.FixtureAddTextFile("afdo_profiles_package/libBar.afdo", ""),
456 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
457 variables.AfdoProfiles = []string{
458 "libTest://afdo_profiles_package:libTest_afdo",
459 "libBar://afdo_profiles_package:libBar_afdo",
460 }
461 }),
462 android.MockFS{
463 "afdo_profiles_package/Android.bp": []byte(`
464 fdo_profile {
465 name: "libTest_afdo",
466 profile: "libTest.afdo",
467 }
468 fdo_profile {
469 name: "libBar_afdo",
470 profile: "libBar.afdo",
471 }
472 `),
473 }.AddToFixture(),
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400474 ).RunTestWithBp(t, bp)
475
Vinh Tran44cb78c2023-03-09 22:07:19 -0500476 expectedCFlagLibTest := "-fprofile-sample-use=afdo_profiles_package/libTest.afdo"
477 expectedCFlagLibBar := "-fprofile-sample-use=afdo_profiles_package/libBar.afdo"
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400478
479 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
Vinh Tran44cb78c2023-03-09 22:07:19 -0500480 libFooAfdoVariantWithLibTest := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest")
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400481
482 libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_shared")
Vinh Tran44cb78c2023-03-09 22:07:19 -0500483 libFooAfdoVariantWithLibBar := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libBar")
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400484
Vinh Tran44cb78c2023-03-09 22:07:19 -0500485 // Check cFlags of afdo-enabled module and the afdo-variant of its static deps
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400486 cFlags := libTest.Rule("cc").Args["cFlags"]
487 if !strings.Contains(cFlags, expectedCFlagLibTest) {
488 t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibTest, cFlags)
489 }
490 cFlags = libBar.Rule("cc").Args["cFlags"]
491 if !strings.Contains(cFlags, expectedCFlagLibBar) {
Vinh Tran44cb78c2023-03-09 22:07:19 -0500492 t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibBar, cFlags)
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400493 }
494
Vinh Tran44cb78c2023-03-09 22:07:19 -0500495 cFlags = libFooAfdoVariantWithLibTest.Rule("cc").Args["cFlags"]
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400496 if !strings.Contains(cFlags, expectedCFlagLibTest) {
Vinh Tran44cb78c2023-03-09 22:07:19 -0500497 t.Errorf("Expected 'libFooAfdoVariantWithLibTest' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibTest, cFlags)
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400498 }
499
Vinh Tran44cb78c2023-03-09 22:07:19 -0500500 cFlags = libFooAfdoVariantWithLibBar.Rule("cc").Args["cFlags"]
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400501 if !strings.Contains(cFlags, expectedCFlagLibBar) {
Vinh Tran44cb78c2023-03-09 22:07:19 -0500502 t.Errorf("Expected 'libBarAfdoVariant' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibBar, cFlags)
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400503 }
504
505 // Check dependency edges of static deps
Vinh Tran44cb78c2023-03-09 22:07:19 -0500506 if !hasDirectDep(result, libTest.Module(), libFooAfdoVariantWithLibTest.Module()) {
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400507 t.Errorf("libTest missing dependency on afdo variant of libFoo")
508 }
509
Vinh Tran44cb78c2023-03-09 22:07:19 -0500510 if !hasDirectDep(result, libBar.Module(), libFooAfdoVariantWithLibBar.Module()) {
511 t.Errorf("libFoo missing dependency on non-afdo variant of libBar")
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400512 }
513}
Yabin Cui01c44562023-04-20 14:07:29 -0700514
515func TestAfdoDepsWithoutProfile(t *testing.T) {
516 t.Parallel()
517 bp := `
518 cc_library_shared {
519 name: "libTest",
520 srcs: ["test.c"],
521 static_libs: ["libFoo"],
522 afdo: true,
523 }
524
525 cc_library_static {
526 name: "libFoo",
527 srcs: ["foo.c"],
528 static_libs: ["libBar"],
529 }
530
531 cc_library_static {
532 name: "libBar",
533 srcs: ["bar.c"],
534 }
535 `
536
537 result := android.GroupFixturePreparers(
538 PrepareForTestWithFdoProfile,
539 prepareForCcTest,
540 ).RunTestWithBp(t, bp)
541
542 // Even without a profile path, the afdo enabled libraries should be built with
543 // -funique-internal-linkage-names.
544 expectedCFlag := "-funique-internal-linkage-names"
545
546 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
547 libFooAfdoVariant := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest")
548 libBarAfdoVariant := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_afdo-libTest")
549
550 // Check cFlags of afdo-enabled module and the afdo-variant of its static deps
551 cFlags := libTest.Rule("cc").Args["cFlags"]
552 if !strings.Contains(cFlags, expectedCFlag) {
553 t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", expectedCFlag, cFlags)
554 }
555
556 cFlags = libFooAfdoVariant.Rule("cc").Args["cFlags"]
557 if !strings.Contains(cFlags, expectedCFlag) {
558 t.Errorf("Expected 'libFooAfdoVariant' to enable afdo, but did not find %q in cflags %q", expectedCFlag, cFlags)
559 }
560
561 cFlags = libBarAfdoVariant.Rule("cc").Args["cFlags"]
562 if !strings.Contains(cFlags, expectedCFlag) {
563 t.Errorf("Expected 'libBarAfdoVariant' to enable afdo, but did not find %q in cflags %q", expectedCFlag, cFlags)
564 }
565 // Check dependency edge from afdo-enabled module to static deps
566 if !hasDirectDep(result, libTest.Module(), libFooAfdoVariant.Module()) {
567 t.Errorf("libTest missing dependency on afdo variant of libFoo")
568 }
569
570 if !hasDirectDep(result, libFooAfdoVariant.Module(), libBarAfdoVariant.Module()) {
571 t.Errorf("libTest missing dependency on afdo variant of libBar")
572 }
573
574 // Verify non-afdo variant exists and doesn't contain afdo
575 libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
576 libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
577
578 cFlags = libFoo.Rule("cc").Args["cFlags"]
579 if strings.Contains(cFlags, expectedCFlag) {
580 t.Errorf("Expected 'libFoo' to not enable afdo, but found %q in cflags %q", expectedCFlag, cFlags)
581 }
582 cFlags = libBar.Rule("cc").Args["cFlags"]
583 if strings.Contains(cFlags, expectedCFlag) {
584 t.Errorf("Expected 'libBar' to not enable afdo, but found %q in cflags %q", expectedCFlag, cFlags)
585 }
586
587 // Check dependency edges of static deps
588 if hasDirectDep(result, libTest.Module(), libFoo.Module()) {
589 t.Errorf("libTest should not depend on non-afdo variant of libFoo")
590 }
591
592 if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
593 t.Errorf("libFoo missing dependency on non-afdo variant of libBar")
594 }
595}