blob: 3eab039215d70584acd27d5041980fcb7960e8f7 [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 (
Liz Kammer8c8e8d52022-10-31 15:53:36 -040018 "strings"
Yi Kongd5954a22022-01-26 17:36:26 +080019 "testing"
20
21 "android/soong/android"
Liz Kammer8c8e8d52022-10-31 15:53:36 -040022
Yi Kongd5954a22022-01-26 17:36:26 +080023 "github.com/google/blueprint"
24)
25
Liz Kammer8c8e8d52022-10-31 15:53:36 -040026type visitDirectDepsInterface interface {
27 VisitDirectDeps(blueprint.Module, func(dep blueprint.Module))
28}
29
30func hasDirectDep(ctx visitDirectDepsInterface, m android.Module, wantDep android.Module) bool {
31 var found bool
32 ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
33 if dep == wantDep {
34 found = true
35 }
36 })
37 return found
38}
39
Yi Kongd5954a22022-01-26 17:36:26 +080040func TestAfdoDeps(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -040041 t.Parallel()
Yi Kongd5954a22022-01-26 17:36:26 +080042 bp := `
Liz Kammer8c8e8d52022-10-31 15:53:36 -040043 cc_library_shared {
Yi Kongd5954a22022-01-26 17:36:26 +080044 name: "libTest",
Colin Cross15fa8142024-02-07 15:09:08 -080045 host_supported: true,
Liz Kammer8c8e8d52022-10-31 15:53:36 -040046 srcs: ["test.c"],
Yi Kongd5954a22022-01-26 17:36:26 +080047 static_libs: ["libFoo"],
48 afdo: true,
Colin Crossda4c89f2024-02-07 15:03:01 -080049 lto: {
50 thin: true,
51 },
Yi Kongd5954a22022-01-26 17:36:26 +080052 }
53
Liz Kammer8c8e8d52022-10-31 15:53:36 -040054 cc_library_static {
Yi Kongd5954a22022-01-26 17:36:26 +080055 name: "libFoo",
Colin Cross15fa8142024-02-07 15:09:08 -080056 host_supported: true,
Liz Kammer8c8e8d52022-10-31 15:53:36 -040057 srcs: ["foo.c"],
Yi Kongd5954a22022-01-26 17:36:26 +080058 static_libs: ["libBar"],
59 }
60
Liz Kammer8c8e8d52022-10-31 15:53:36 -040061 cc_library_static {
Yi Kongd5954a22022-01-26 17:36:26 +080062 name: "libBar",
Colin Cross15fa8142024-02-07 15:09:08 -080063 host_supported: true,
Liz Kammer8c8e8d52022-10-31 15:53:36 -040064 srcs: ["bar.c"],
Yi Kongd5954a22022-01-26 17:36:26 +080065 }
66 `
Yi Kongd5954a22022-01-26 17:36:26 +080067
68 result := android.GroupFixturePreparers(
Vinh Trancde10162023-03-09 22:07:19 -050069 PrepareForTestWithFdoProfile,
Yi Kongd5954a22022-01-26 17:36:26 +080070 prepareForCcTest,
Vinh Tran44cb78c2023-03-09 22:07:19 -050071 android.FixtureAddTextFile("afdo_profiles_package/libTest.afdo", ""),
72 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
73 variables.AfdoProfiles = []string{
74 "libTest://afdo_profiles_package:libTest_afdo",
75 }
76 }),
77 android.MockFS{
78 "afdo_profiles_package/Android.bp": []byte(`
79 fdo_profile {
80 name: "libTest_afdo",
Colin Crossda4c89f2024-02-07 15:03:01 -080081 arch: {
82 arm64: {
83 profile: "libTest.afdo",
84 },
85 },
Vinh Tran44cb78c2023-03-09 22:07:19 -050086 }
87 `),
88 }.AddToFixture(),
Yi Kongd5954a22022-01-26 17:36:26 +080089 ).RunTestWithBp(t, bp)
90
Colin Crossda4c89f2024-02-07 15:03:01 -080091 profileSampleCFlag := "-fprofile-sample-use=afdo_profiles_package/libTest.afdo"
92 uniqueInternalLinkageNamesCFlag := "-funique-internal-linkage-names"
93 afdoLtoLdFlag := "-Wl,-plugin-opt,-import-instr-limit=40"
94 noAfdoLtoLdFlag := "-Wl,-plugin-opt,-import-instr-limit=5"
Yi Kongd5954a22022-01-26 17:36:26 +080095
Vinh Tran44cb78c2023-03-09 22:07:19 -050096 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
97 libFooAfdoVariant := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest")
98 libBarAfdoVariant := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_afdo-libTest")
99
100 // Check cFlags of afdo-enabled module and the afdo-variant of its static deps
101 cFlags := libTest.Rule("cc").Args["cFlags"]
Colin Crossda4c89f2024-02-07 15:03:01 -0800102 if !strings.Contains(cFlags, profileSampleCFlag) {
103 t.Errorf("Expected 'libTest' to enable afdo profile, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
104 }
105 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
106 t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
107 }
108
109 ldFlags := libTest.Rule("ld").Args["ldFlags"]
110 if !strings.Contains(ldFlags, afdoLtoLdFlag) {
111 t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in ldflags %q", afdoLtoLdFlag, ldFlags)
Vinh Tran44cb78c2023-03-09 22:07:19 -0500112 }
113
114 cFlags = libFooAfdoVariant.Rule("cc").Args["cFlags"]
Colin Crossda4c89f2024-02-07 15:03:01 -0800115 if !strings.Contains(cFlags, profileSampleCFlag) {
116 t.Errorf("Expected 'libFooAfdoVariant' to enable afdo profile, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
117 }
118 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
119 t.Errorf("Expected 'libFooAfdoVariant' to enable afdo, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
Vinh Tran44cb78c2023-03-09 22:07:19 -0500120 }
121
122 cFlags = libBarAfdoVariant.Rule("cc").Args["cFlags"]
Colin Crossda4c89f2024-02-07 15:03:01 -0800123 if !strings.Contains(cFlags, profileSampleCFlag) {
124 t.Errorf("Expected 'libBarAfdoVariant' to enable afdo profile, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
125 }
126 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
127 t.Errorf("Expected 'libBarAfdoVariant' to enable afdo, but did not find %q in cflags %q", profileSampleCFlag, cFlags)
Vinh Tran44cb78c2023-03-09 22:07:19 -0500128 }
129
130 // Check dependency edge from afdo-enabled module to static deps
131 if !hasDirectDep(result, libTest.Module(), libFooAfdoVariant.Module()) {
Yi Kongd5954a22022-01-26 17:36:26 +0800132 t.Errorf("libTest missing dependency on afdo variant of libFoo")
133 }
134
Vinh Tran44cb78c2023-03-09 22:07:19 -0500135 if !hasDirectDep(result, libFooAfdoVariant.Module(), libBarAfdoVariant.Module()) {
Yi Kongd5954a22022-01-26 17:36:26 +0800136 t.Errorf("libTest missing dependency on afdo variant of libBar")
137 }
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400138
Vinh Tran44cb78c2023-03-09 22:07:19 -0500139 // Verify non-afdo variant exists and doesn't contain afdo
140 libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
141 libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400142
143 cFlags = libFoo.Rule("cc").Args["cFlags"]
Colin Crossda4c89f2024-02-07 15:03:01 -0800144 if strings.Contains(cFlags, profileSampleCFlag) {
145 t.Errorf("Expected 'libFoo' to not enable afdo profile, but found %q in cflags %q", profileSampleCFlag, cFlags)
146 }
147 if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
148 t.Errorf("Expected 'libFoo' to not enable afdo, but found %q in cflags %q", profileSampleCFlag, cFlags)
Vinh Tran44cb78c2023-03-09 22:07:19 -0500149 }
150 cFlags = libBar.Rule("cc").Args["cFlags"]
Colin Crossda4c89f2024-02-07 15:03:01 -0800151 if strings.Contains(cFlags, profileSampleCFlag) {
152 t.Errorf("Expected 'libBar' to not enable afdo profile, but found %q in cflags %q", profileSampleCFlag, cFlags)
153 }
154 if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
155 t.Errorf("Expected 'libBar' to not enable afdo, but found %q in cflags %q", profileSampleCFlag, cFlags)
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400156 }
157
Vinh Tran44cb78c2023-03-09 22:07:19 -0500158 // Check dependency edges of static deps
159 if hasDirectDep(result, libTest.Module(), libFoo.Module()) {
160 t.Errorf("libTest should not depend on non-afdo variant of libFoo")
161 }
162
163 if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
164 t.Errorf("libFoo missing dependency on non-afdo variant of libBar")
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400165 }
Colin Crossda4c89f2024-02-07 15:03:01 -0800166
167 // Verify that the arm variant does not have FDO since the fdo_profile module only has a profile for arm64
168 libTest32 := result.ModuleForTests("libTest", "android_arm_armv7-a-neon_shared")
169 libFooAfdoVariant32 := result.ModuleForTests("libFoo", "android_arm_armv7-a-neon_static_afdo-libTest_lto-thin")
170 libBarAfdoVariant32 := result.ModuleForTests("libBar", "android_arm_armv7-a-neon_static_afdo-libTest_lto-thin")
171
172 cFlags = libTest32.Rule("cc").Args["cFlags"]
173 if strings.Contains(cFlags, profileSampleCFlag) {
174 t.Errorf("Expected arm32 'libTest' not to enable afdo, but found %q in cflags %q", profileSampleCFlag, cFlags)
175 }
176
177 // TODO(b/324141705): when the fdo_profile module doesn't provide a source file the dependencies don't get
178 // -funique-internal-linkage-names but the module does.
179 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
180 t.Errorf("Expected arm32 'libTest' to enable -funique-internal-linkage-names but did not find %q in cflags %q",
181 uniqueInternalLinkageNamesCFlag, cFlags)
182 }
183
184 ldFlags = libTest32.Rule("ld").Args["ldFlags"]
185 if !strings.Contains(ldFlags, noAfdoLtoLdFlag) {
186 t.Errorf("Expected arm32 'libTest' to not enable afdo, but did not find %q in ldflags %q", noAfdoLtoLdFlag, ldFlags)
187 }
188 if strings.Contains(ldFlags, afdoLtoLdFlag) {
189 t.Errorf("Expected arm32 'libTest' to not enable afdo, but found %q in ldflags %q", afdoLtoLdFlag, ldFlags)
190 }
191
192 // Check dependency edge from afdo-enabled module to static deps
193 if !hasDirectDep(result, libTest32.Module(), libFooAfdoVariant32.Module()) {
194 t.Errorf("arm32 libTest missing dependency on afdo variant of libFoo")
195 }
196
197 if !hasDirectDep(result, libFooAfdoVariant32.Module(), libBarAfdoVariant32.Module()) {
198 t.Errorf("arm32 libTest missing dependency on afdo variant of libBar")
199 }
200
201 cFlags = libFooAfdoVariant32.Rule("cc").Args["cFlags"]
202 if strings.Contains(cFlags, profileSampleCFlag) {
203 t.Errorf("Expected arm32 'libFoo' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
204 }
205 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
206 t.Errorf("Expected arm32 'libFoo' to enable afdo, but did not find %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
207 }
208 cFlags = libBarAfdoVariant32.Rule("cc").Args["cFlags"]
209 if strings.Contains(cFlags, profileSampleCFlag) {
210 t.Errorf("Expected arm32 'libBar' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
211 }
212 if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
213 t.Errorf("Expected arm32 'libBar' to enable afdo, but did not find %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
214 }
215
Colin Cross15fa8142024-02-07 15:09:08 -0800216 // Verify that the host variants don't enable afdo
217 libTestHost := result.ModuleForTests("libTest", result.Config.BuildOSTarget.String()+"_shared")
218 libFooHost := result.ModuleForTests("libFoo", result.Config.BuildOSTarget.String()+"_static_lto-thin")
219 libBarHost := result.ModuleForTests("libBar", result.Config.BuildOSTarget.String()+"_static_lto-thin")
220
221 cFlags = libTestHost.Rule("cc").Args["cFlags"]
222 if strings.Contains(cFlags, profileSampleCFlag) {
223 t.Errorf("Expected host 'libTest' to not enable afdo profile, but found %q in cflags %q", profileSampleCFlag, cFlags)
224 }
225
226 if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
227 t.Errorf("Expected host 'libTest' to not enable afdo but found %q in cflags %q",
228 uniqueInternalLinkageNamesCFlag, cFlags)
229 }
230
231 ldFlags = libTestHost.Rule("ld").Args["ldFlags"]
232 if !strings.Contains(ldFlags, noAfdoLtoLdFlag) {
233 t.Errorf("Expected host 'libTest' to not enable afdo, but did not find %q in ldflags %q", noAfdoLtoLdFlag, ldFlags)
234 }
235 if strings.Contains(ldFlags, afdoLtoLdFlag) {
236 t.Errorf("Expected host 'libTest' to not enable afdo, but found %q in ldflags %q", afdoLtoLdFlag, ldFlags)
237 }
238
239 // Check dependency edge from afdo-enabled module to static deps
240 if !hasDirectDep(result, libTestHost.Module(), libFooHost.Module()) {
241 t.Errorf("host libTest missing dependency on non-afdo variant of libFoo")
242 }
243
244 if !hasDirectDep(result, libFooHost.Module(), libBarHost.Module()) {
245 t.Errorf("host libTest missing dependency on non-afdo variant of libBar")
246 }
247
248 cFlags = libFooHost.Rule("cc").Args["cFlags"]
249 if strings.Contains(cFlags, profileSampleCFlag) {
250 t.Errorf("Expected host 'libFoo' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
251 }
252 if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
253 t.Errorf("Expected host 'libFoo' to not enable afdo, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
254 }
255 cFlags = libBarHost.Rule("cc").Args["cFlags"]
256 if strings.Contains(cFlags, profileSampleCFlag) {
257 t.Errorf("Expected host 'libBar' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
258 }
259 if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) {
260 t.Errorf("Expected host 'libBar' to not enable afdo, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags)
261 }
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400262}
263
264func TestAfdoEnabledOnStaticDepNoAfdo(t *testing.T) {
Liz Kammer7c5d1592022-10-31 16:27:38 -0400265 t.Parallel()
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400266 bp := `
267 cc_library_shared {
268 name: "libTest",
269 srcs: ["foo.c"],
270 static_libs: ["libFoo"],
271 }
272
273 cc_library_static {
274 name: "libFoo",
275 srcs: ["foo.c"],
276 static_libs: ["libBar"],
277 afdo: true, // TODO(b/256670524): remove support for enabling afdo from static only libraries, this can only propagate from shared libraries/binaries
278 }
279
280 cc_library_static {
281 name: "libBar",
282 }
283 `
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400284
285 result := android.GroupFixturePreparers(
286 prepareForCcTest,
Vinh Trancde10162023-03-09 22:07:19 -0500287 PrepareForTestWithFdoProfile,
Vinh Tran44cb78c2023-03-09 22:07:19 -0500288 android.FixtureAddTextFile("toolchain/pgo-profiles/sampling/libFoo.afdo", ""),
289 android.MockFS{
290 "afdo_profiles_package/Android.bp": []byte(`
291 soong_namespace {
292 }
293 fdo_profile {
294 name: "libFoo_afdo",
295 profile: "libFoo.afdo",
296 }
297 `),
298 }.AddToFixture(),
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400299 ).RunTestWithBp(t, bp)
300
301 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared").Module()
302 libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
303 libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static").Module()
304
305 if !hasDirectDep(result, libTest, libFoo.Module()) {
Colin Crossda4c89f2024-02-07 15:03:01 -0800306 t.Errorf("libTest missing dependency on non-afdo variant of libFoo")
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400307 }
308
309 if !hasDirectDep(result, libFoo.Module(), libBar) {
Colin Crossda4c89f2024-02-07 15:03:01 -0800310 t.Errorf("libFoo missing dependency on non-afdo variant of libBar")
Liz Kammer8c8e8d52022-10-31 15:53:36 -0400311 }
312
313 fooVariants := result.ModuleVariantsForTests("foo")
314 for _, v := range fooVariants {
315 if strings.Contains(v, "afdo-") {
316 t.Errorf("Expected no afdo variant of 'foo', got %q", v)
317 }
318 }
319
320 cFlags := libFoo.Rule("cc").Args["cFlags"]
321 if w := "-fprofile-sample-accurate"; strings.Contains(cFlags, w) {
322 t.Errorf("Expected 'foo' to not enable afdo, but found %q in cflags %q", w, cFlags)
323 }
324
325 barVariants := result.ModuleVariantsForTests("bar")
326 for _, v := range barVariants {
327 if strings.Contains(v, "afdo-") {
328 t.Errorf("Expected no afdo variant of 'bar', got %q", v)
329 }
330 }
Yi Kongd5954a22022-01-26 17:36:26 +0800331}
Vinh Tran9c6080c2022-12-05 14:55:38 -0500332
333func TestAfdoEnabledWithRuntimeDepNoAfdo(t *testing.T) {
334 bp := `
335 cc_library {
336 name: "libTest",
337 srcs: ["foo.c"],
338 runtime_libs: ["libFoo"],
339 afdo: true,
340 }
341
342 cc_library {
343 name: "libFoo",
344 }
345 `
Vinh Tran9c6080c2022-12-05 14:55:38 -0500346
347 result := android.GroupFixturePreparers(
348 prepareForCcTest,
Vinh Trancde10162023-03-09 22:07:19 -0500349 PrepareForTestWithFdoProfile,
Vinh Tran44cb78c2023-03-09 22:07:19 -0500350 android.FixtureAddTextFile("afdo_profiles_package/libTest.afdo", ""),
351 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
352 variables.AfdoProfiles = []string{
353 "libTest://afdo_profiles_package:libTest_afdo",
354 }
355 }),
356 android.MockFS{
357 "afdo_profiles_package/Android.bp": []byte(`
358 fdo_profile {
359 name: "libTest_afdo",
360 profile: "libTest.afdo",
361 }
362 `),
363 }.AddToFixture(),
Vinh Tran9c6080c2022-12-05 14:55:38 -0500364 ).RunTestWithBp(t, bp)
365
366 libFooVariants := result.ModuleVariantsForTests("libFoo")
367 for _, v := range libFooVariants {
368 if strings.Contains(v, "afdo-") {
369 t.Errorf("Expected no afdo variant of 'foo', got %q", v)
370 }
371 }
372}
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400373
374func TestAfdoEnabledWithMultiArchs(t *testing.T) {
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400375 bp := `
376 cc_library_shared {
377 name: "foo",
378 srcs: ["test.c"],
379 afdo: true,
380 compile_multilib: "both",
381 }
382`
383 result := android.GroupFixturePreparers(
Vinh Trancde10162023-03-09 22:07:19 -0500384 PrepareForTestWithFdoProfile,
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400385 prepareForCcTest,
Vinh Tran44cb78c2023-03-09 22:07:19 -0500386 android.FixtureAddTextFile("afdo_profiles_package/foo_arm.afdo", ""),
387 android.FixtureAddTextFile("afdo_profiles_package/foo_arm64.afdo", ""),
388 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
389 variables.AfdoProfiles = []string{
390 "foo://afdo_profiles_package:foo_afdo",
391 }
392 }),
393 android.MockFS{
394 "afdo_profiles_package/Android.bp": []byte(`
395 soong_namespace {
396 }
397 fdo_profile {
398 name: "foo_afdo",
399 arch: {
400 arm: {
401 profile: "foo_arm.afdo",
402 },
403 arm64: {
404 profile: "foo_arm64.afdo",
405 }
406 }
407 }
408 `),
409 }.AddToFixture(),
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400410 ).RunTestWithBp(t, bp)
411
412 fooArm := result.ModuleForTests("foo", "android_arm_armv7-a-neon_shared")
413 fooArmCFlags := fooArm.Rule("cc").Args["cFlags"]
Vinh Tran44cb78c2023-03-09 22:07:19 -0500414 if w := "-fprofile-sample-use=afdo_profiles_package/foo_arm.afdo"; !strings.Contains(fooArmCFlags, w) {
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400415 t.Errorf("Expected 'foo' to enable afdo, but did not find %q in cflags %q", w, fooArmCFlags)
416 }
417
418 fooArm64 := result.ModuleForTests("foo", "android_arm64_armv8-a_shared")
419 fooArm64CFlags := fooArm64.Rule("cc").Args["cFlags"]
Vinh Tran44cb78c2023-03-09 22:07:19 -0500420 if w := "-fprofile-sample-use=afdo_profiles_package/foo_arm64.afdo"; !strings.Contains(fooArm64CFlags, w) {
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400421 t.Errorf("Expected 'foo' to enable afdo, but did not find %q in cflags %q", w, fooArm64CFlags)
422 }
423}
424
425func TestMultipleAfdoRDeps(t *testing.T) {
426 t.Parallel()
427 bp := `
428 cc_library_shared {
429 name: "libTest",
430 srcs: ["test.c"],
431 static_libs: ["libFoo"],
432 afdo: true,
433 }
434
435 cc_library_shared {
436 name: "libBar",
437 srcs: ["bar.c"],
438 static_libs: ["libFoo"],
439 afdo: true,
440 }
441
442 cc_library_static {
443 name: "libFoo",
444 srcs: ["foo.c"],
445 }
446 `
447
448 result := android.GroupFixturePreparers(
Vinh Trancde10162023-03-09 22:07:19 -0500449 PrepareForTestWithFdoProfile,
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400450 prepareForCcTest,
Vinh Tran44cb78c2023-03-09 22:07:19 -0500451 android.FixtureAddTextFile("afdo_profiles_package/libTest.afdo", ""),
452 android.FixtureAddTextFile("afdo_profiles_package/libBar.afdo", ""),
453 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
454 variables.AfdoProfiles = []string{
455 "libTest://afdo_profiles_package:libTest_afdo",
456 "libBar://afdo_profiles_package:libBar_afdo",
457 }
458 }),
459 android.MockFS{
460 "afdo_profiles_package/Android.bp": []byte(`
461 fdo_profile {
462 name: "libTest_afdo",
463 profile: "libTest.afdo",
464 }
465 fdo_profile {
466 name: "libBar_afdo",
467 profile: "libBar.afdo",
468 }
469 `),
470 }.AddToFixture(),
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400471 ).RunTestWithBp(t, bp)
472
Vinh Tran44cb78c2023-03-09 22:07:19 -0500473 expectedCFlagLibTest := "-fprofile-sample-use=afdo_profiles_package/libTest.afdo"
474 expectedCFlagLibBar := "-fprofile-sample-use=afdo_profiles_package/libBar.afdo"
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400475
476 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
Vinh Tran44cb78c2023-03-09 22:07:19 -0500477 libFooAfdoVariantWithLibTest := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest")
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400478
479 libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_shared")
Vinh Tran44cb78c2023-03-09 22:07:19 -0500480 libFooAfdoVariantWithLibBar := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libBar")
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400481
Vinh Tran44cb78c2023-03-09 22:07:19 -0500482 // Check cFlags of afdo-enabled module and the afdo-variant of its static deps
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400483 cFlags := libTest.Rule("cc").Args["cFlags"]
484 if !strings.Contains(cFlags, expectedCFlagLibTest) {
485 t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibTest, cFlags)
486 }
487 cFlags = libBar.Rule("cc").Args["cFlags"]
488 if !strings.Contains(cFlags, expectedCFlagLibBar) {
Vinh Tran44cb78c2023-03-09 22:07:19 -0500489 t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibBar, cFlags)
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400490 }
491
Vinh Tran44cb78c2023-03-09 22:07:19 -0500492 cFlags = libFooAfdoVariantWithLibTest.Rule("cc").Args["cFlags"]
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400493 if !strings.Contains(cFlags, expectedCFlagLibTest) {
Vinh Tran44cb78c2023-03-09 22:07:19 -0500494 t.Errorf("Expected 'libFooAfdoVariantWithLibTest' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibTest, cFlags)
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400495 }
496
Vinh Tran44cb78c2023-03-09 22:07:19 -0500497 cFlags = libFooAfdoVariantWithLibBar.Rule("cc").Args["cFlags"]
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400498 if !strings.Contains(cFlags, expectedCFlagLibBar) {
Vinh Tran44cb78c2023-03-09 22:07:19 -0500499 t.Errorf("Expected 'libBarAfdoVariant' to enable afdo, but did not find %q in cflags %q", expectedCFlagLibBar, cFlags)
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400500 }
501
502 // Check dependency edges of static deps
Vinh Tran44cb78c2023-03-09 22:07:19 -0500503 if !hasDirectDep(result, libTest.Module(), libFooAfdoVariantWithLibTest.Module()) {
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400504 t.Errorf("libTest missing dependency on afdo variant of libFoo")
505 }
506
Vinh Tran44cb78c2023-03-09 22:07:19 -0500507 if !hasDirectDep(result, libBar.Module(), libFooAfdoVariantWithLibBar.Module()) {
508 t.Errorf("libFoo missing dependency on non-afdo variant of libBar")
Vinh Tran2e7b0fd2023-03-27 11:30:19 -0400509 }
510}
Yabin Cui01c44562023-04-20 14:07:29 -0700511
512func TestAfdoDepsWithoutProfile(t *testing.T) {
513 t.Parallel()
514 bp := `
515 cc_library_shared {
516 name: "libTest",
517 srcs: ["test.c"],
518 static_libs: ["libFoo"],
519 afdo: true,
520 }
521
522 cc_library_static {
523 name: "libFoo",
524 srcs: ["foo.c"],
525 static_libs: ["libBar"],
526 }
527
528 cc_library_static {
529 name: "libBar",
530 srcs: ["bar.c"],
531 }
532 `
533
534 result := android.GroupFixturePreparers(
535 PrepareForTestWithFdoProfile,
536 prepareForCcTest,
537 ).RunTestWithBp(t, bp)
538
539 // Even without a profile path, the afdo enabled libraries should be built with
540 // -funique-internal-linkage-names.
541 expectedCFlag := "-funique-internal-linkage-names"
542
543 libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
544 libFooAfdoVariant := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest")
545 libBarAfdoVariant := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_afdo-libTest")
546
547 // Check cFlags of afdo-enabled module and the afdo-variant of its static deps
548 cFlags := libTest.Rule("cc").Args["cFlags"]
549 if !strings.Contains(cFlags, expectedCFlag) {
550 t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", expectedCFlag, cFlags)
551 }
552
553 cFlags = libFooAfdoVariant.Rule("cc").Args["cFlags"]
554 if !strings.Contains(cFlags, expectedCFlag) {
555 t.Errorf("Expected 'libFooAfdoVariant' to enable afdo, but did not find %q in cflags %q", expectedCFlag, cFlags)
556 }
557
558 cFlags = libBarAfdoVariant.Rule("cc").Args["cFlags"]
559 if !strings.Contains(cFlags, expectedCFlag) {
560 t.Errorf("Expected 'libBarAfdoVariant' to enable afdo, but did not find %q in cflags %q", expectedCFlag, cFlags)
561 }
562 // Check dependency edge from afdo-enabled module to static deps
563 if !hasDirectDep(result, libTest.Module(), libFooAfdoVariant.Module()) {
564 t.Errorf("libTest missing dependency on afdo variant of libFoo")
565 }
566
567 if !hasDirectDep(result, libFooAfdoVariant.Module(), libBarAfdoVariant.Module()) {
568 t.Errorf("libTest missing dependency on afdo variant of libBar")
569 }
570
571 // Verify non-afdo variant exists and doesn't contain afdo
572 libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
573 libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
574
575 cFlags = libFoo.Rule("cc").Args["cFlags"]
576 if strings.Contains(cFlags, expectedCFlag) {
577 t.Errorf("Expected 'libFoo' to not enable afdo, but found %q in cflags %q", expectedCFlag, cFlags)
578 }
579 cFlags = libBar.Rule("cc").Args["cFlags"]
580 if strings.Contains(cFlags, expectedCFlag) {
581 t.Errorf("Expected 'libBar' to not enable afdo, but found %q in cflags %q", expectedCFlag, cFlags)
582 }
583
584 // Check dependency edges of static deps
585 if hasDirectDep(result, libTest.Module(), libFoo.Module()) {
586 t.Errorf("libTest should not depend on non-afdo variant of libFoo")
587 }
588
589 if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
590 t.Errorf("libFoo missing dependency on non-afdo variant of libBar")
591 }
592}