diff options
author | 2016-06-16 16:50:52 +0100 | |
---|---|---|
committer | 2016-07-01 13:26:24 +0100 | |
commit | e90049140fdfb89080e5cc9b000b0c9be8c18bcd (patch) | |
tree | 66b45c052b6778fabd7847a44af5e610808fa867 /compiler | |
parent | a77ceae14a7be2494874d9256327efa8c522e234 (diff) |
Create a typedef for HInstruction::GetInputs() return type.
And some other cleanup after
https://android-review.googlesource.com/230742
Test: No new tests. ART test suite passed (tested on host).
Change-Id: I4743bf17544d0234c6ccb46dd0c1b9aae5c93e17
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/optimizing/bounds_check_elimination.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/graph_checker.cc | 14 | ||||
-rw-r--r-- | compiler/optimizing/graph_visualizer.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/induction_var_analysis.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/nodes.cc | 6 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 33 | ||||
-rw-r--r-- | compiler/optimizing/pc_relative_fixups_x86.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/pretty_printer.h | 2 | ||||
-rw-r--r-- | compiler/optimizing/reference_type_propagation.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/register_allocator.cc | 2 | ||||
-rw-r--r-- | compiler/optimizing/ssa_builder.cc | 4 | ||||
-rw-r--r-- | compiler/optimizing/ssa_liveness_analysis.cc | 6 | ||||
-rw-r--r-- | compiler/utils/transform_array_ref.h | 8 | ||||
-rw-r--r-- | compiler/utils/transform_array_ref_test.cc | 42 | ||||
-rw-r--r-- | compiler/utils/transform_iterator.h | 6 | ||||
-rw-r--r-- | compiler/utils/transform_iterator_test.cc | 2 |
17 files changed, 98 insertions, 45 deletions
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc index e9fcfe2bed..5f27e147e3 100644 --- a/compiler/optimizing/bounds_check_elimination.cc +++ b/compiler/optimizing/bounds_check_elimination.cc @@ -912,9 +912,9 @@ class BCEVisitor : public HGraphVisitor { static bool HasSameInputAtBackEdges(HPhi* phi) { DCHECK(phi->IsLoopHeaderPhi()); - auto&& inputs = phi->GetInputs(); + HConstInputsRef inputs = phi->GetInputs(); // Start with input 1. Input 0 is from the incoming block. - HInstruction* input1 = inputs[1]; + const HInstruction* input1 = inputs[1]; DCHECK(phi->GetBlock()->GetLoopInformation()->IsBackEdge( *phi->GetBlock()->GetPredecessors()[1])); for (size_t i = 2; i < inputs.size(); ++i) { diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 12aa15207c..4520f9b3e3 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -111,7 +111,7 @@ static bool CheckTypeConsistency(HInstruction* instruction) { << " " << locations->Out(); } - auto&& inputs = instruction->GetInputs(); + HConstInputsRef inputs = instruction->GetInputs(); for (size_t i = 0; i < inputs.size(); ++i) { DCHECK(CheckType(inputs[i]->GetType(), locations->InAt(i))) << inputs[i]->GetType() << " " << locations->InAt(i); diff --git a/compiler/optimizing/graph_checker.cc b/compiler/optimizing/graph_checker.cc index 2bd2403dd6..c8cba205fd 100644 --- a/compiler/optimizing/graph_checker.cc +++ b/compiler/optimizing/graph_checker.cc @@ -362,7 +362,7 @@ void GraphChecker::VisitInstruction(HInstruction* instruction) { instruction->GetId())); } size_t use_index = use.GetIndex(); - auto&& user_inputs = user->GetInputs(); + HConstInputsRef user_inputs = user->GetInputs(); if ((use_index >= user_inputs.size()) || (user_inputs[use_index] != instruction)) { AddError(StringPrintf("User %s:%d of instruction %s:%d has a wrong " "UseListNode index.", @@ -490,7 +490,7 @@ void GraphChecker::VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) { VisitInstruction(invoke); if (invoke->IsStaticWithExplicitClinitCheck()) { - HInstruction* last_input = invoke->GetInputs().back(); + const HInstruction* last_input = invoke->GetInputs().back(); if (last_input == nullptr) { AddError(StringPrintf("Static invoke %s:%d marked as having an explicit clinit check " "has a null pointer as last input.", @@ -664,17 +664,19 @@ void GraphChecker::HandleLoop(HBasicBlock* loop_header) { } } -static bool IsSameSizeConstant(HInstruction* insn1, HInstruction* insn2) { +static bool IsSameSizeConstant(const HInstruction* insn1, const HInstruction* insn2) { return insn1->IsConstant() && insn2->IsConstant() && Primitive::Is64BitType(insn1->GetType()) == Primitive::Is64BitType(insn2->GetType()); } -static bool IsConstantEquivalent(HInstruction* insn1, HInstruction* insn2, BitVector* visited) { +static bool IsConstantEquivalent(const HInstruction* insn1, + const HInstruction* insn2, + BitVector* visited) { if (insn1->IsPhi() && insn1->AsPhi()->IsVRegEquivalentOf(insn2)) { - auto&& insn1_inputs = insn1->GetInputs(); - auto&& insn2_inputs = insn2->GetInputs(); + HConstInputsRef insn1_inputs = insn1->GetInputs(); + HConstInputsRef insn2_inputs = insn2->GetInputs(); if (insn1_inputs.size() != insn2_inputs.size()) { return false; } diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc index 4af8d1985b..9d67373321 100644 --- a/compiler/optimizing/graph_visualizer.cc +++ b/compiler/optimizing/graph_visualizer.cc @@ -511,7 +511,7 @@ class HGraphVisualizerPrinter : public HGraphDelegateVisitor { void PrintInstruction(HInstruction* instruction) { output_ << instruction->DebugName(); - auto&& inputs = instruction->GetInputs(); + HConstInputsRef inputs = instruction->GetInputs(); if (!inputs.empty()) { StringList input_list; for (const HInstruction* input : inputs) { diff --git a/compiler/optimizing/induction_var_analysis.cc b/compiler/optimizing/induction_var_analysis.cc index 52426d73c6..129c2a94b5 100644 --- a/compiler/optimizing/induction_var_analysis.cc +++ b/compiler/optimizing/induction_var_analysis.cc @@ -341,7 +341,7 @@ HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::TransferPhi(HLoopIn HInstruction* phi, size_t input_index) { // Match all phi inputs from input_index onwards exactly. - auto&& inputs = phi->GetInputs(); + HInputsRef inputs = phi->GetInputs(); DCHECK_LT(input_index, inputs.size()); InductionInfo* a = LookupInfo(loop, inputs[input_index]); for (size_t i = input_index + 1; i < inputs.size(); i++) { @@ -464,7 +464,7 @@ HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::TransferCnv(Inducti HInductionVarAnalysis::InductionInfo* HInductionVarAnalysis::SolvePhi(HInstruction* phi, size_t input_index) { // Match all phi inputs from input_index onwards exactly. - auto&& inputs = phi->GetInputs(); + HInputsRef inputs = phi->GetInputs(); DCHECK_LT(input_index, inputs.size()); auto ita = cycle_.find(inputs[input_index]); if (ita != cycle_.end()) { diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index c2c212b66f..d557f42968 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -754,7 +754,7 @@ bool HBasicBlock::Dominates(HBasicBlock* other) const { } static void UpdateInputsUsers(HInstruction* instruction) { - auto&& inputs = instruction->GetInputs(); + HInputsRef inputs = instruction->GetInputs(); for (size_t i = 0; i < inputs.size(); ++i) { inputs[i]->AddUseAt(instruction, i); } @@ -1312,8 +1312,8 @@ bool HInstruction::Equals(const HInstruction* other) const { DCHECK_EQ(GetKind(), other->GetKind()); if (!InstructionDataEquals(other)) return false; if (GetType() != other->GetType()) return false; - auto&& inputs = GetInputs(); - auto&& other_inputs = other->GetInputs(); + HConstInputsRef inputs = GetInputs(); + HConstInputsRef other_inputs = other->GetInputs(); if (inputs.size() != other_inputs.size()) return false; for (size_t i = 0; i != inputs.size(); ++i) { if (inputs[i] != other_inputs[i]) return false; diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 6b2c33e668..d98dd0608b 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -1415,6 +1415,21 @@ class HUserRecord : public ValueObject { typename HUseList<T>::iterator before_use_node_; }; +// Helper class that extracts the input instruction from HUserRecord<HInstruction*>. +// This is used for HInstruction::GetInputs() to return a container wrapper providing +// HInstruction* values even though the underlying container has HUserRecord<>s. +struct HInputExtractor { + HInstruction* operator()(HUserRecord<HInstruction*>& record) const { + return record.GetInstruction(); + } + const HInstruction* operator()(const HUserRecord<HInstruction*>& record) const { + return record.GetInstruction(); + } +}; + +using HInputsRef = TransformArrayRef<HUserRecord<HInstruction*>, HInputExtractor>; +using HConstInputsRef = TransformArrayRef<const HUserRecord<HInstruction*>, HInputExtractor>; + /** * Side-effects representation. * @@ -1804,20 +1819,12 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> { const_cast<HInstruction*>(this)->GetInputRecords()); } - auto GetInputs() { - return MakeTransformArrayRef( - GetInputRecords(), - [](HUserRecord<HInstruction*>& record) -> HInstruction* { - return record.GetInstruction(); - }); + HInputsRef GetInputs() { + return MakeTransformArrayRef(GetInputRecords(), HInputExtractor()); } - auto GetInputs() const { - return MakeTransformArrayRef( - GetInputRecords(), - [](const HUserRecord<HInstruction*>& record) -> const HInstruction* { - return record.GetInstruction(); - }); + HConstInputsRef GetInputs() const { + return MakeTransformArrayRef(GetInputRecords(), HInputExtractor()); } size_t InputCount() const { return GetInputRecords().size(); } @@ -2408,7 +2415,7 @@ class HPhi FINAL : public HInstruction { bool IsDead() const { return !IsLive(); } bool IsLive() const { return GetPackedFlag<kFlagIsLive>(); } - bool IsVRegEquivalentOf(HInstruction* other) const { + bool IsVRegEquivalentOf(const HInstruction* other) const { return other != nullptr && other->IsPhi() && other->AsPhi()->GetBlock() == GetBlock() diff --git a/compiler/optimizing/pc_relative_fixups_x86.cc b/compiler/optimizing/pc_relative_fixups_x86.cc index 93116f8bab..921f3dfff6 100644 --- a/compiler/optimizing/pc_relative_fixups_x86.cc +++ b/compiler/optimizing/pc_relative_fixups_x86.cc @@ -211,7 +211,7 @@ class PCRelativeHandlerVisitor : public HGraphVisitor { } // Ensure that we can load FP arguments from the constant area. - auto&& inputs = invoke->GetInputs(); + HInputsRef inputs = invoke->GetInputs(); for (size_t i = 0; i < inputs.size(); i++) { HConstant* input = inputs[i]->AsConstant(); if (input != nullptr && Primitive::IsFloatingPointType(input->GetType())) { diff --git a/compiler/optimizing/pretty_printer.h b/compiler/optimizing/pretty_printer.h index f9bef6809f..5891350894 100644 --- a/compiler/optimizing/pretty_printer.h +++ b/compiler/optimizing/pretty_printer.h @@ -39,7 +39,7 @@ class HPrettyPrinter : public HGraphVisitor { } void PrintPostInstruction(HInstruction* instruction) { - auto&& inputs = instruction->GetInputs(); + HConstInputsRef inputs = instruction->GetInputs(); if (!inputs.empty()) { PrintString("("); bool first = true; diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc index 3dfd7282cd..965d5ee4f9 100644 --- a/compiler/optimizing/reference_type_propagation.cc +++ b/compiler/optimizing/reference_type_propagation.cc @@ -816,10 +816,10 @@ void ReferenceTypePropagation::UpdateBoundType(HBoundType* instr) { void ReferenceTypePropagation::UpdatePhi(HPhi* instr) { DCHECK(instr->IsLive()); - auto&& inputs = instr->GetInputs(); + HInputsRef inputs = instr->GetInputs(); size_t first_input_index_not_null = 0; while (first_input_index_not_null < inputs.size() && - inputs[first_input_index_not_null]->IsNullConstant()) { + inputs[first_input_index_not_null]->IsNullConstant()) { first_input_index_not_null++; } if (first_input_index_not_null == inputs.size()) { diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc index 4a6b835e80..9d99668484 100644 --- a/compiler/optimizing/register_allocator.cc +++ b/compiler/optimizing/register_allocator.cc @@ -753,7 +753,7 @@ bool RegisterAllocator::TryAllocateFreeReg(LiveInterval* current) { if (defined_by != nullptr && !current->IsSplit()) { LocationSummary* locations = defined_by->GetLocations(); if (!locations->OutputCanOverlapWithInputs() && locations->Out().IsUnallocated()) { - auto&& inputs = defined_by->GetInputs(); + HInputsRef inputs = defined_by->GetInputs(); for (size_t i = 0; i < inputs.size(); ++i) { // Take the last interval of the input. It is the location of that interval // that will be used at `defined_by`. diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc index ed50c69b5d..5a574d9af7 100644 --- a/compiler/optimizing/ssa_builder.cc +++ b/compiler/optimizing/ssa_builder.cc @@ -181,7 +181,7 @@ bool SsaBuilder::TypeInputsOfPhi(HPhi* phi, ArenaVector<HPhi*>* worklist) { return true; } else { DCHECK(common_type == Primitive::kPrimNot || Primitive::IsFloatingPointType(common_type)); - auto&& inputs = phi->GetInputs(); + HInputsRef inputs = phi->GetInputs(); for (size_t i = 0; i < inputs.size(); ++i) { HInstruction* input = inputs[i]; if (input->GetType() != common_type) { @@ -617,7 +617,7 @@ HPhi* SsaBuilder::GetFloatDoubleOrReferenceEquivalentOfPhi(HPhi* phi, Primitive: || (next->AsPhi()->GetRegNumber() != phi->GetRegNumber()) || (next->GetType() != type)) { ArenaAllocator* allocator = graph_->GetArena(); - auto&& inputs = phi->GetInputs(); + HInputsRef inputs = phi->GetInputs(); HPhi* new_phi = new (allocator) HPhi(allocator, phi->GetRegNumber(), inputs.size(), type); // Copy the inputs. Note that the graph may not be correctly typed diff --git a/compiler/optimizing/ssa_liveness_analysis.cc b/compiler/optimizing/ssa_liveness_analysis.cc index 212d93532c..7af4302884 100644 --- a/compiler/optimizing/ssa_liveness_analysis.cc +++ b/compiler/optimizing/ssa_liveness_analysis.cc @@ -177,7 +177,7 @@ void SsaLivenessAnalysis::ComputeLiveness() { static void RecursivelyProcessInputs(HInstruction* current, HInstruction* actual_user, BitVector* live_in) { - auto&& inputs = current->GetInputs(); + HInputsRef inputs = current->GetInputs(); for (size_t i = 0; i < inputs.size(); ++i) { HInstruction* input = inputs[i]; bool has_in_location = current->GetLocations()->InAt(i).IsValid(); @@ -431,7 +431,7 @@ int LiveInterval::FindFirstRegisterHint(size_t* free_until, // If the instruction dies at the phi assignment, we can try having the // same register. if (end == user->GetBlock()->GetPredecessors()[input_index]->GetLifetimeEnd()) { - auto&& inputs = user->GetInputs(); + HInputsRef inputs = user->GetInputs(); for (size_t i = 0; i < inputs.size(); ++i) { if (i == input_index) { continue; @@ -472,7 +472,7 @@ int LiveInterval::FindHintAtDefinition() const { if (defined_by_->IsPhi()) { // Try to use the same register as one of the inputs. const ArenaVector<HBasicBlock*>& predecessors = defined_by_->GetBlock()->GetPredecessors(); - auto&& inputs = defined_by_->GetInputs(); + HInputsRef inputs = defined_by_->GetInputs(); for (size_t i = 0; i < inputs.size(); ++i) { size_t end = predecessors[i]->GetLifetimeEnd(); LiveInterval* input_interval = inputs[i]->GetLiveInterval()->GetSiblingAt(end - 1); diff --git a/compiler/utils/transform_array_ref.h b/compiler/utils/transform_array_ref.h index 6297b88e69..a6da34fb40 100644 --- a/compiler/utils/transform_array_ref.h +++ b/compiler/utils/transform_array_ref.h @@ -70,6 +70,11 @@ class TransformArrayRef { TransformArrayRef(const ArrayRef<OtherBT>& base, Function fn) : data_(base, fn) { } + template <typename OtherBT, + typename = typename std::enable_if<std::is_same<BaseType, const OtherBT>::value>::type> + TransformArrayRef(const TransformArrayRef<OtherBT, Function>& other) + : TransformArrayRef(other.base(), other.GetFunction()) { } + // Assignment operators. TransformArrayRef& operator=(const TransformArrayRef& other) = default; @@ -149,6 +154,9 @@ class TransformArrayRef { } Data data_; + + template <typename OtherBT, typename OtherFunction> + friend class TransformArrayRef; }; template <typename BaseType, typename Function> diff --git a/compiler/utils/transform_array_ref_test.cc b/compiler/utils/transform_array_ref_test.cc index 2593fade2f..8d71fd7179 100644 --- a/compiler/utils/transform_array_ref_test.cc +++ b/compiler/utils/transform_array_ref_test.cc @@ -160,6 +160,48 @@ TEST(TransformArrayRef, ConstAndNonConstRef) { taref[i] = transform_input[i]; } ASSERT_EQ(std::vector<ValueHolder>({ 24, 37, 11, 71 }), transformed); + + const std::vector<ValueHolder>& cinput = input; + + auto ctaref = MakeTransformArrayRef(cinput, ref); + static_assert(std::is_same<int, decltype(ctaref)::value_type>::value, "value_type"); + static_assert(std::is_same<const int*, decltype(ctaref)::pointer>::value, "pointer"); + static_assert(std::is_same<const int&, decltype(ctaref)::reference>::value, "reference"); + static_assert(std::is_same<const int*, decltype(ctaref)::const_pointer>::value, "const_pointer"); + static_assert(std::is_same<const int&, decltype(ctaref)::const_reference>::value, + "const_reference"); + + std::copy(ctaref.begin(), ctaref.end(), std::back_inserter(output)); + ASSERT_EQ(std::vector<int>({ 1, 0, 1, 0, 3, 1 }), output); + output.clear(); + + std::copy(ctaref.cbegin(), ctaref.cend(), std::back_inserter(output)); + ASSERT_EQ(std::vector<int>({ 1, 0, 1, 0, 3, 1 }), output); + output.clear(); + + std::copy(ctaref.rbegin(), ctaref.rend(), std::back_inserter(output)); + ASSERT_EQ(std::vector<int>({ 1, 3, 0, 1, 0, 1 }), output); + output.clear(); + + std::copy(ctaref.crbegin(), ctaref.crend(), std::back_inserter(output)); + ASSERT_EQ(std::vector<int>({ 1, 3, 0, 1, 0, 1 }), output); + output.clear(); + + ASSERT_EQ(cinput.size(), ctaref.size()); + ASSERT_EQ(cinput.empty(), ctaref.empty()); + ASSERT_EQ(cinput.front().value, ctaref.front()); + ASSERT_EQ(cinput.back().value, ctaref.back()); + + for (size_t i = 0; i != cinput.size(); ++i) { + ASSERT_EQ(cinput[i].value, ctaref[i]); + } + + // Test conversion adding const. + decltype(ctaref) ctaref2 = taref; + ASSERT_EQ(taref.size(), ctaref2.size()); + for (size_t i = 0; i != taref.size(); ++i) { + ASSERT_EQ(taref[i], ctaref2[i]); + } } } // namespace art diff --git a/compiler/utils/transform_iterator.h b/compiler/utils/transform_iterator.h index f0769d4800..3bc9046408 100644 --- a/compiler/utils/transform_iterator.h +++ b/compiler/utils/transform_iterator.h @@ -44,11 +44,7 @@ class TransformIterator { typename std::iterator_traits<BaseIterator>::iterator_category>::value, "Transform iterator base must be an input iterator."); - using InputType = - typename std::conditional< - std::is_same<void, typename std::iterator_traits<BaseIterator>::reference>::value, - typename std::iterator_traits<BaseIterator>::value_type, - typename std::iterator_traits<BaseIterator>::reference>::type; + using InputType = typename std::iterator_traits<BaseIterator>::reference; using ResultType = typename std::result_of<Function(InputType)>::type; public: diff --git a/compiler/utils/transform_iterator_test.cc b/compiler/utils/transform_iterator_test.cc index dbb4779330..57ff0a62ac 100644 --- a/compiler/utils/transform_iterator_test.cc +++ b/compiler/utils/transform_iterator_test.cc @@ -20,8 +20,6 @@ #include <type_traits> #include <vector> -#include <array> - #include "gtest/gtest.h" #include "utils/transform_iterator.h" |