summaryrefslogtreecommitdiff
path: root/compiler/optimizing/loop_optimization.cc
diff options
context:
space:
mode:
author Santiago Aboy Solanes <solanes@google.com> 2024-03-11 09:48:58 +0000
committer Santiago Aboy Solanes <solanes@google.com> 2024-03-15 13:29:20 +0000
commitc89c15e6063fef79a3d4a0a7f8402c527257e3fa (patch)
tree746f97f08db3c913773f92095881263259e53c8b /compiler/optimizing/loop_optimization.cc
parent33fa1ccb3f29d981d8b74c4f38fe432793d74c97 (diff)
Make HLoopOptimization::VectorMode an enum class
Bug: 329034512 Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b Test: m test-art-host-gtest Change-Id: I182c8568dfe7c9bc1cbb05dc4a3265336063b469
Diffstat (limited to 'compiler/optimizing/loop_optimization.cc')
-rw-r--r--compiler/optimizing/loop_optimization.cc77
1 files changed, 43 insertions, 34 deletions
diff --git a/compiler/optimizing/loop_optimization.cc b/compiler/optimizing/loop_optimization.cc
index 28712302c5..ed66d65373 100644
--- a/compiler/optimizing/loop_optimization.cc
+++ b/compiler/optimizing/loop_optimization.cc
@@ -532,13 +532,12 @@ HLoopOptimization::HLoopOptimization(HGraph* graph,
vector_permanent_map_(nullptr),
vector_external_set_(nullptr),
predicate_info_map_(nullptr),
- vector_mode_(kSequential),
+ vector_mode_(VectorMode::kSequential),
vector_preheader_(nullptr),
vector_header_(nullptr),
vector_body_(nullptr),
vector_index_(nullptr),
- arch_loop_helper_(ArchNoOptsLoopHelper::Create(codegen, global_allocator_)) {
-}
+ arch_loop_helper_(ArchNoOptsLoopHelper::Create(codegen, global_allocator_)) {}
bool HLoopOptimization::Run() {
// Skip if there is no loop or the graph has irreducible loops.
@@ -1316,7 +1315,7 @@ void HLoopOptimization::VectorizePredicated(LoopNode* node,
// <vectorized-loop-body>
HBasicBlock* preheader_for_vector_loop =
graph_->TransformLoopForVectorization(vector_header_, vector_body_, exit);
- vector_mode_ = kVector;
+ vector_mode_ = VectorMode::kVector;
GenerateNewLoopPredicated(node,
preheader_for_vector_loop,
vector_index_,
@@ -1327,7 +1326,7 @@ void HLoopOptimization::VectorizePredicated(LoopNode* node,
// for ( ; i < stc; i += 1)
// <loop-body>
if (needs_disambiguation_test) {
- vector_mode_ = kSequential;
+ vector_mode_ = VectorMode::kSequential;
HBasicBlock* preheader_for_cleanup_loop =
graph_->TransformLoopForVectorization(vector_header_, vector_body_, exit);
// Use "Traditional" version for the sequential loop.
@@ -1466,7 +1465,7 @@ void HLoopOptimization::VectorizeTraditional(LoopNode* node,
// moved around during suspend checks, since all analysis was based on
// nothing more than the Android runtime alignment conventions.
if (ptc != nullptr) {
- vector_mode_ = kSequential;
+ vector_mode_ = VectorMode::kSequential;
HBasicBlock* preheader_for_peeling_loop =
graph_->TransformLoopForVectorization(vector_header_, vector_body_, exit);
GenerateNewLoopScalarOrTraditional(node,
@@ -1480,7 +1479,7 @@ void HLoopOptimization::VectorizeTraditional(LoopNode* node,
// Generate vector loop, possibly further unrolled:
// for ( ; i < vtc; i += chunk)
// <vectorized-loop-body>
- vector_mode_ = kVector;
+ vector_mode_ = VectorMode::kVector;
HBasicBlock* preheader_for_vector_loop =
graph_->TransformLoopForVectorization(vector_header_, vector_body_, exit);
GenerateNewLoopScalarOrTraditional(node,
@@ -1494,7 +1493,7 @@ void HLoopOptimization::VectorizeTraditional(LoopNode* node,
// for ( ; i < stc; i += 1)
// <loop-body>
if (needs_cleanup) {
- vector_mode_ = kSequential;
+ vector_mode_ = VectorMode::kSequential;
HBasicBlock* preheader_for_cleanup_loop =
graph_->TransformLoopForVectorization(vector_header_, vector_body_, exit);
GenerateNewLoopScalarOrTraditional(node,
@@ -1572,7 +1571,7 @@ void HLoopOptimization::GenerateNewLoopScalarOrTraditional(LoopNode* node,
HInstruction* hi,
HInstruction* step,
uint32_t unroll) {
- DCHECK(unroll == 1 || vector_mode_ == kVector);
+ DCHECK(unroll == 1 || vector_mode_ == VectorMode::kVector);
DataType::Type induc_type = lo->GetType();
HPhi* phi = InitializeForNewLoop(new_preheader, lo);
@@ -1594,7 +1593,7 @@ void HLoopOptimization::GenerateNewLoopPredicated(LoopNode* node,
HInstruction* hi,
HInstruction* step) {
DCHECK(IsInPredicatedVectorizationMode());
- DCHECK_EQ(vector_mode_, kVector);
+ DCHECK_EQ(vector_mode_, VectorMode::kVector);
DataType::Type induc_type = lo->GetType();
HPhi* phi = InitializeForNewLoop(new_preheader, lo);
@@ -1881,7 +1880,7 @@ bool HLoopOptimization::VectorizeUse(LoopNode* node,
size_from >= size_vec &&
VectorizeUse(node, opa, generate_code, type, restrictions))) {
if (generate_code) {
- if (vector_mode_ == kVector) {
+ if (vector_mode_ == VectorMode::kVector) {
vector_map_->Put(instruction, vector_map_->Get(opa)); // operand pass-through
} else {
GenerateVecOp(instruction, vector_map_->Get(opa), nullptr, type);
@@ -1957,7 +1956,7 @@ bool HLoopOptimization::VectorizeUse(LoopNode* node,
// Accept shift operator for vectorizable/invariant operands.
// TODO: accept symbolic, albeit loop invariant shift factors.
DCHECK(r != nullptr);
- if (generate_code && vector_mode_ != kVector) { // de-idiom
+ if (generate_code && vector_mode_ != VectorMode::kVector) { // de-idiom
r = opa;
}
int64_t distance = 0;
@@ -1985,7 +1984,7 @@ bool HLoopOptimization::VectorizeUse(LoopNode* node,
}
// Accept ABS(x) for vectorizable operand.
DCHECK(r != nullptr);
- if (generate_code && vector_mode_ != kVector) { // de-idiom
+ if (generate_code && vector_mode_ != VectorMode::kVector) { // de-idiom
r = opa;
}
if (VectorizeUse(node, r, generate_code, type, restrictions)) {
@@ -2181,7 +2180,7 @@ void HLoopOptimization::GenerateVecInv(HInstruction* org, DataType::Type type) {
if (vector_map_->find(org) == vector_map_->end()) {
// In scalar code, just use a self pass-through for scalar invariants
// (viz. expression remains itself).
- if (vector_mode_ == kSequential) {
+ if (vector_mode_ == VectorMode::kSequential) {
vector_map_->Put(org, org);
return;
}
@@ -2229,7 +2228,7 @@ void HLoopOptimization::GenerateVecMem(HInstruction* org,
DataType::Type type) {
uint32_t dex_pc = org->GetDexPc();
HInstruction* vector = nullptr;
- if (vector_mode_ == kVector) {
+ if (vector_mode_ == VectorMode::kVector) {
// Vector store or load.
bool is_string_char_at = false;
HInstruction* base = org->InputAt(0);
@@ -2261,7 +2260,7 @@ void HLoopOptimization::GenerateVecMem(HInstruction* org,
}
} else {
// Scalar store or load.
- DCHECK(vector_mode_ == kSequential);
+ DCHECK(vector_mode_ == VectorMode::kSequential);
if (opb != nullptr) {
DataType::Type component_type = org->AsArraySet()->GetComponentType();
vector = new (global_allocator_) HArraySet(
@@ -2279,7 +2278,7 @@ void HLoopOptimization::GenerateVecReductionPhi(HPhi* orig_phi) {
DCHECK(reductions_->find(orig_phi) != reductions_->end());
DCHECK(reductions_->Get(orig_phi->InputAt(1)) == orig_phi);
HInstruction* vector = nullptr;
- if (vector_mode_ == kSequential) {
+ if (vector_mode_ == VectorMode::kSequential) {
HPhi* new_phi = new (global_allocator_) HPhi(
global_allocator_, kNoRegNumber, 0, orig_phi->GetType());
vector_header_->AddPhi(new_phi);
@@ -2308,7 +2307,7 @@ void HLoopOptimization::GenerateVecReductionPhiInputs(HPhi* phi, HInstruction* r
DCHECK(new_phi->IsVecOperation());
}
// Prepare the new initialization.
- if (vector_mode_ == kVector) {
+ if (vector_mode_ == VectorMode::kVector) {
// Generate a [initial, 0, .., 0] vector for add or
// a [initial, initial, .., initial] vector for min/max.
HVecOperation* red_vector = new_red->AsVecOperation();
@@ -2371,13 +2370,13 @@ HInstruction* HLoopOptimization::ReduceAndExtractIfNeeded(HInstruction* instruct
return instruction;
}
-#define GENERATE_VEC(x, y) \
- if (vector_mode_ == kVector) { \
- vector = (x); \
- } else { \
- DCHECK(vector_mode_ == kSequential); \
- vector = (y); \
- } \
+#define GENERATE_VEC(x, y) \
+ if (vector_mode_ == VectorMode::kVector) { \
+ vector = (x); \
+ } else { \
+ DCHECK(vector_mode_ == VectorMode::kSequential); \
+ vector = (y); \
+ } \
break;
HInstruction* HLoopOptimization::GenerateVecOp(HInstruction* org,
@@ -2455,7 +2454,7 @@ HInstruction* HLoopOptimization::GenerateVecOp(HInstruction* org,
new (global_allocator_) HAbs(org_type, opa, dex_pc));
case HInstruction::kEqual: {
// Special case.
- DCHECK_EQ(vector_mode_, kVector);
+ DCHECK_EQ(vector_mode_, VectorMode::kVector);
vector = new (global_allocator_)
HVecCondition(global_allocator_, opa, opb, type, vector_length_, dex_pc);
}
@@ -2521,14 +2520,14 @@ bool HLoopOptimization::VectorizeHalvingAddIdiom(LoopNode* node,
// Accept recognized halving add for vectorizable operands. Vectorized code uses the
// shorthand idiomatic operation. Sequential code uses the original scalar expressions.
DCHECK(r != nullptr && s != nullptr);
- if (generate_code && vector_mode_ != kVector) { // de-idiom
+ if (generate_code && vector_mode_ != VectorMode::kVector) { // de-idiom
r = instruction->InputAt(0);
s = instruction->InputAt(1);
}
if (VectorizeUse(node, r, generate_code, type, restrictions) &&
VectorizeUse(node, s, generate_code, type, restrictions)) {
if (generate_code) {
- if (vector_mode_ == kVector) {
+ if (vector_mode_ == VectorMode::kVector) {
vector_map_->Put(instruction, new (global_allocator_) HVecHalvingAdd(
global_allocator_,
vector_map_->Get(r),
@@ -2597,14 +2596,14 @@ bool HLoopOptimization::VectorizeSADIdiom(LoopNode* node,
// Accept SAD idiom for vectorizable operands. Vectorized code uses the shorthand
// idiomatic operation. Sequential code uses the original scalar expressions.
DCHECK(r != nullptr && s != nullptr);
- if (generate_code && vector_mode_ != kVector) { // de-idiom
+ if (generate_code && vector_mode_ != VectorMode::kVector) { // de-idiom
r = s = abs->InputAt(0);
}
if (VectorizeUse(node, acc, generate_code, sub_type, restrictions) &&
VectorizeUse(node, r, generate_code, sub_type, restrictions) &&
VectorizeUse(node, s, generate_code, sub_type, restrictions)) {
if (generate_code) {
- if (vector_mode_ == kVector) {
+ if (vector_mode_ == VectorMode::kVector) {
vector_map_->Put(instruction, new (global_allocator_) HVecSADAccumulate(
global_allocator_,
vector_map_->Get(acc),
@@ -2670,7 +2669,7 @@ bool HLoopOptimization::VectorizeDotProdIdiom(LoopNode* node,
DCHECK(r != nullptr && s != nullptr);
// Accept dot product idiom for vectorizable operands. Vectorized code uses the shorthand
// idiomatic operation. Sequential code uses the original scalar expressions.
- if (generate_code && vector_mode_ != kVector) { // de-idiom
+ if (generate_code && vector_mode_ != VectorMode::kVector) { // de-idiom
r = mul_left;
s = mul_right;
}
@@ -2678,7 +2677,7 @@ bool HLoopOptimization::VectorizeDotProdIdiom(LoopNode* node,
VectorizeUse(node, r, generate_code, op_type, restrictions) &&
VectorizeUse(node, s, generate_code, op_type, restrictions)) {
if (generate_code) {
- if (vector_mode_ == kVector) {
+ if (vector_mode_ == VectorMode::kVector) {
vector_map_->Put(instruction, new (global_allocator_) HVecDotProd(
global_allocator_,
vector_map_->Get(acc),
@@ -2756,7 +2755,7 @@ bool HLoopOptimization::VectorizeIfCondition(LoopNode* node,
return false;
}
- if (generate_code && vector_mode_ != kVector) { // de-idiom
+ if (generate_code && vector_mode_ != VectorMode::kVector) { // de-idiom
opa_promoted = opa;
opb_promoted = opb;
}
@@ -2768,7 +2767,7 @@ bool HLoopOptimization::VectorizeIfCondition(LoopNode* node,
vector_map_->Get(opa_promoted),
vector_map_->Get(opb_promoted),
type);
- DCHECK_EQ(vector_mode_, kVector);
+ DCHECK_EQ(vector_mode_, VectorMode::kVector);
HInstruction* vec_pred_not = new (global_allocator_)
HVecPredNot(global_allocator_, vec_cond, type, vector_length_, hif->GetDexPc());
@@ -3161,4 +3160,14 @@ void HLoopOptimization::InitPredicateInfoMap(LoopNode* node,
back_edge_info->SetControlPredicate(header_info->GetTruePredicate());
}
+std::ostream& operator<<(std::ostream& os, const HLoopOptimization::VectorMode& mode) {
+ switch (mode) {
+ case HLoopOptimization::VectorMode::kSequential:
+ return os << "kSequential";
+ case HLoopOptimization::VectorMode::kVector:
+ return os << "kVector";
+ }
+ return os;
+}
+
} // namespace art