diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2016-04-06 06:38:15 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2016-04-06 06:38:15 +0000 |
commit | bdfc984679b81e021634336f5f8f5dfca5b294a8 (patch) | |
tree | d79da9aff4e35fcfaaba65515a4635531206f850 /llvm/unittests/IR/FunctionTest.cpp | |
parent | 5811c40bb37f8642d05b12d8113b8a40d6b23b72 (diff) | |
download | bcm5719-llvm-bdfc984679b81e021634336f5f8f5dfca5b294a8.tar.gz bcm5719-llvm-bdfc984679b81e021634336f5f8f5dfca5b294a8.zip |
IRMover: Steal arguments when moving functions, NFC
Instead of copying arguments from the source function to the
destination, steal them. This has a few advantages.
- The ValueMap doesn't need to be seeded with (or cleared of)
Arguments.
- Often the destination function won't have created any arguments yet,
so this avoids malloc traffic.
- Argument names don't need to be copied.
Because argument lists are lazy, this required a new
Function::stealArgumentListFrom helper.
llvm-svn: 265519
Diffstat (limited to 'llvm/unittests/IR/FunctionTest.cpp')
-rw-r--r-- | llvm/unittests/IR/FunctionTest.cpp | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/llvm/unittests/IR/FunctionTest.cpp b/llvm/unittests/IR/FunctionTest.cpp new file mode 100644 index 00000000000..8dd1f2bb00b --- /dev/null +++ b/llvm/unittests/IR/FunctionTest.cpp @@ -0,0 +1,106 @@ +//===- FunctionTest.cpp - Function unit tests -----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/Function.h" +#include "gtest/gtest.h" +using namespace llvm; + +namespace { + +TEST(FunctionTest, hasLazyArguments) { + LLVMContext C; + + Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)}; + FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false); + + // Functions start out with lazy arguments. + std::unique_ptr<Function> F( + Function::Create(FTy, GlobalValue::ExternalLinkage, "F")); + EXPECT_TRUE(F->hasLazyArguments()); + + // Checking for empty or size shouldn't force arguments to be instantiated. + EXPECT_FALSE(F->arg_empty()); + EXPECT_TRUE(F->hasLazyArguments()); + EXPECT_EQ(2u, F->arg_size()); + EXPECT_TRUE(F->hasLazyArguments()); + + // The argument list should be populated at first access. + (void)F->arg_begin(); + EXPECT_FALSE(F->hasLazyArguments()); +} + +TEST(FunctionTest, stealArgumentListFrom) { + LLVMContext C; + + Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)}; + FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false); + std::unique_ptr<Function> F1( + Function::Create(FTy, GlobalValue::ExternalLinkage, "F1")); + std::unique_ptr<Function> F2( + Function::Create(FTy, GlobalValue::ExternalLinkage, "F1")); + EXPECT_TRUE(F1->hasLazyArguments()); + EXPECT_TRUE(F2->hasLazyArguments()); + + // Steal arguments before they've been accessed. Nothing should change; both + // functions should still have lazy arguments. + // + // steal(empty); drop (empty) + F1->stealArgumentListFrom(*F2); + EXPECT_TRUE(F1->hasLazyArguments()); + EXPECT_TRUE(F2->hasLazyArguments()); + + // Save arguments from F1 for later assertions. F1 won't have lazy arguments + // anymore. + SmallVector<Argument *, 4> Args; + for (Argument &A : F1->args()) + Args.push_back(&A); + EXPECT_EQ(2u, Args.size()); + EXPECT_FALSE(F1->hasLazyArguments()); + + // Steal arguments from F1 to F2. F1's arguments should be lazy again. + // + // steal(real); drop (empty) + F2->stealArgumentListFrom(*F1); + EXPECT_TRUE(F1->hasLazyArguments()); + EXPECT_FALSE(F2->hasLazyArguments()); + unsigned I = 0; + for (Argument &A : F2->args()) + EXPECT_EQ(Args[I++], &A); + EXPECT_EQ(2u, I); + + // Check that arguments in F1 don't have pointer equality with the saved ones. + // This also instantiates F1's arguments. + I = 0; + for (Argument &A : F1->args()) + EXPECT_NE(Args[I++], &A); + EXPECT_EQ(2u, I); + EXPECT_FALSE(F1->hasLazyArguments()); + EXPECT_FALSE(F2->hasLazyArguments()); + + // Steal back from F2. F2's arguments should be lazy again. + // + // steal(real); drop (real) + F1->stealArgumentListFrom(*F2); + EXPECT_FALSE(F1->hasLazyArguments()); + EXPECT_TRUE(F2->hasLazyArguments()); + I = 0; + for (Argument &A : F1->args()) + EXPECT_EQ(Args[I++], &A); + EXPECT_EQ(2u, I); + + // Steal from F2 a second time. Now both functions should have lazy + // arguments. + // + // steal(empty); drop (real) + F1->stealArgumentListFrom(*F2); + EXPECT_TRUE(F1->hasLazyArguments()); + EXPECT_TRUE(F2->hasLazyArguments()); +} + +} // end namespace |