From da4c89f750be870d6b1e507afb31a5bf9265e9cd Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 7 Feb 2024 15:03:01 -0800 Subject: [PATCH] Add more AFDO tests Add more coverage to the afdo tests for the arm32 variant of a module that only has an arm64 profile, for the -funique-internal-linkage-names flag, and for the interaction between LTO linker flags and AFDO. Test: afdo_test.go Change-Id: I3ed4ce033c2431ea3e2fee536744b5e5b4cad296 --- cc/afdo_test.go | 108 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 94 insertions(+), 14 deletions(-) diff --git a/cc/afdo_test.go b/cc/afdo_test.go index b250ad1a1..65dc032d4 100644 --- a/cc/afdo_test.go +++ b/cc/afdo_test.go @@ -45,6 +45,9 @@ func TestAfdoDeps(t *testing.T) { srcs: ["test.c"], static_libs: ["libFoo"], afdo: true, + lto: { + thin: true, + }, } cc_library_static { @@ -72,13 +75,20 @@ func TestAfdoDeps(t *testing.T) { "afdo_profiles_package/Android.bp": []byte(` fdo_profile { name: "libTest_afdo", - profile: "libTest.afdo", + arch: { + arm64: { + profile: "libTest.afdo", + }, + }, } `), }.AddToFixture(), ).RunTestWithBp(t, bp) - expectedCFlag := "-fprofile-sample-use=afdo_profiles_package/libTest.afdo" + profileSampleCFlag := "-fprofile-sample-use=afdo_profiles_package/libTest.afdo" + uniqueInternalLinkageNamesCFlag := "-funique-internal-linkage-names" + afdoLtoLdFlag := "-Wl,-plugin-opt,-import-instr-limit=40" + noAfdoLtoLdFlag := "-Wl,-plugin-opt,-import-instr-limit=5" libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared") libFooAfdoVariant := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest") @@ -86,18 +96,32 @@ func TestAfdoDeps(t *testing.T) { // Check cFlags of afdo-enabled module and the afdo-variant of its static deps cFlags := libTest.Rule("cc").Args["cFlags"] - if !strings.Contains(cFlags, expectedCFlag) { - t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", expectedCFlag, cFlags) + if !strings.Contains(cFlags, profileSampleCFlag) { + t.Errorf("Expected 'libTest' to enable afdo profile, but did not find %q in cflags %q", profileSampleCFlag, cFlags) + } + if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { + t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", profileSampleCFlag, cFlags) + } + + ldFlags := libTest.Rule("ld").Args["ldFlags"] + if !strings.Contains(ldFlags, afdoLtoLdFlag) { + t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in ldflags %q", afdoLtoLdFlag, ldFlags) } cFlags = libFooAfdoVariant.Rule("cc").Args["cFlags"] - if !strings.Contains(cFlags, expectedCFlag) { - t.Errorf("Expected 'libFooAfdoVariant' to enable afdo, but did not find %q in cflags %q", expectedCFlag, cFlags) + if !strings.Contains(cFlags, profileSampleCFlag) { + t.Errorf("Expected 'libFooAfdoVariant' to enable afdo profile, but did not find %q in cflags %q", profileSampleCFlag, cFlags) + } + if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { + t.Errorf("Expected 'libFooAfdoVariant' to enable afdo, but did not find %q in cflags %q", profileSampleCFlag, cFlags) } cFlags = libBarAfdoVariant.Rule("cc").Args["cFlags"] - if !strings.Contains(cFlags, expectedCFlag) { - t.Errorf("Expected 'libBarAfdoVariant' to enable afdo, but did not find %q in cflags %q", expectedCFlag, cFlags) + if !strings.Contains(cFlags, profileSampleCFlag) { + t.Errorf("Expected 'libBarAfdoVariant' to enable afdo profile, but did not find %q in cflags %q", profileSampleCFlag, cFlags) + } + if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { + t.Errorf("Expected 'libBarAfdoVariant' to enable afdo, but did not find %q in cflags %q", profileSampleCFlag, cFlags) } // Check dependency edge from afdo-enabled module to static deps @@ -114,12 +138,18 @@ func TestAfdoDeps(t *testing.T) { libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static") cFlags = libFoo.Rule("cc").Args["cFlags"] - if strings.Contains(cFlags, expectedCFlag) { - t.Errorf("Expected 'libFoo' to not enable afdo, but found %q in cflags %q", expectedCFlag, cFlags) + if strings.Contains(cFlags, profileSampleCFlag) { + t.Errorf("Expected 'libFoo' to not enable afdo profile, but found %q in cflags %q", profileSampleCFlag, cFlags) + } + if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { + t.Errorf("Expected 'libFoo' to not enable afdo, but found %q in cflags %q", profileSampleCFlag, cFlags) } cFlags = libBar.Rule("cc").Args["cFlags"] - if strings.Contains(cFlags, expectedCFlag) { - t.Errorf("Expected 'libBar' to not enable afdo, but found %q in cflags %q", expectedCFlag, cFlags) + if strings.Contains(cFlags, profileSampleCFlag) { + t.Errorf("Expected 'libBar' to not enable afdo profile, but found %q in cflags %q", profileSampleCFlag, cFlags) + } + if strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { + t.Errorf("Expected 'libBar' to not enable afdo, but found %q in cflags %q", profileSampleCFlag, cFlags) } // Check dependency edges of static deps @@ -130,6 +160,56 @@ func TestAfdoDeps(t *testing.T) { if !hasDirectDep(result, libFoo.Module(), libBar.Module()) { t.Errorf("libFoo missing dependency on non-afdo variant of libBar") } + + // Verify that the arm variant does not have FDO since the fdo_profile module only has a profile for arm64 + libTest32 := result.ModuleForTests("libTest", "android_arm_armv7-a-neon_shared") + libFooAfdoVariant32 := result.ModuleForTests("libFoo", "android_arm_armv7-a-neon_static_afdo-libTest_lto-thin") + libBarAfdoVariant32 := result.ModuleForTests("libBar", "android_arm_armv7-a-neon_static_afdo-libTest_lto-thin") + + cFlags = libTest32.Rule("cc").Args["cFlags"] + if strings.Contains(cFlags, profileSampleCFlag) { + t.Errorf("Expected arm32 'libTest' not to enable afdo, but found %q in cflags %q", profileSampleCFlag, cFlags) + } + + // TODO(b/324141705): when the fdo_profile module doesn't provide a source file the dependencies don't get + // -funique-internal-linkage-names but the module does. + if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { + t.Errorf("Expected arm32 'libTest' to enable -funique-internal-linkage-names but did not find %q in cflags %q", + uniqueInternalLinkageNamesCFlag, cFlags) + } + + ldFlags = libTest32.Rule("ld").Args["ldFlags"] + if !strings.Contains(ldFlags, noAfdoLtoLdFlag) { + t.Errorf("Expected arm32 'libTest' to not enable afdo, but did not find %q in ldflags %q", noAfdoLtoLdFlag, ldFlags) + } + if strings.Contains(ldFlags, afdoLtoLdFlag) { + t.Errorf("Expected arm32 'libTest' to not enable afdo, but found %q in ldflags %q", afdoLtoLdFlag, ldFlags) + } + + // Check dependency edge from afdo-enabled module to static deps + if !hasDirectDep(result, libTest32.Module(), libFooAfdoVariant32.Module()) { + t.Errorf("arm32 libTest missing dependency on afdo variant of libFoo") + } + + if !hasDirectDep(result, libFooAfdoVariant32.Module(), libBarAfdoVariant32.Module()) { + t.Errorf("arm32 libTest missing dependency on afdo variant of libBar") + } + + cFlags = libFooAfdoVariant32.Rule("cc").Args["cFlags"] + if strings.Contains(cFlags, profileSampleCFlag) { + t.Errorf("Expected arm32 'libFoo' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags) + } + if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { + t.Errorf("Expected arm32 'libFoo' to enable afdo, but did not find %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags) + } + cFlags = libBarAfdoVariant32.Rule("cc").Args["cFlags"] + if strings.Contains(cFlags, profileSampleCFlag) { + t.Errorf("Expected arm32 'libBar' to not enable afdo profile, but found %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags) + } + if !strings.Contains(cFlags, uniqueInternalLinkageNamesCFlag) { + t.Errorf("Expected arm32 'libBar' to enable afdo, but did not find %q in cflags %q", uniqueInternalLinkageNamesCFlag, cFlags) + } + } func TestAfdoEnabledOnStaticDepNoAfdo(t *testing.T) { @@ -174,11 +254,11 @@ func TestAfdoEnabledOnStaticDepNoAfdo(t *testing.T) { libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static").Module() if !hasDirectDep(result, libTest, libFoo.Module()) { - t.Errorf("libTest missing dependency on afdo variant of libFoo") + t.Errorf("libTest missing dependency on non-afdo variant of libFoo") } if !hasDirectDep(result, libFoo.Module(), libBar) { - t.Errorf("libFoo missing dependency on afdo variant of libBar") + t.Errorf("libFoo missing dependency on non-afdo variant of libBar") } fooVariants := result.ModuleVariantsForTests("foo")