1 /* Copyright (C) 2018 The Android Open Source Project
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  */
15 
16 #include "instruction_simplifier_x86.h"
17 #include "instruction_simplifier_x86_shared.h"
18 #include "code_generator_x86.h"
19 
20 namespace art {
21 
22 namespace x86 {
23 
24 class InstructionSimplifierX86Visitor : public HGraphVisitor {
25  public:
InstructionSimplifierX86Visitor(HGraph * graph,CodeGenerator * codegen,OptimizingCompilerStats * stats)26   InstructionSimplifierX86Visitor(HGraph* graph,
27                                   CodeGenerator* codegen,
28                                   OptimizingCompilerStats* stats)
29       : HGraphVisitor(graph),
30         codegen_(down_cast<CodeGeneratorX86*>(codegen)),
31         stats_(stats) {}
32 
RecordSimplification()33   void RecordSimplification() {
34     MaybeRecordStat(stats_, MethodCompilationStat::kInstructionSimplificationsArch);
35   }
36 
HasAVX2()37   bool HasAVX2() {
38     return (codegen_->GetInstructionSetFeatures().HasAVX2());
39   }
40 
VisitBasicBlock(HBasicBlock * block)41   void VisitBasicBlock(HBasicBlock* block) override {
42     for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) {
43       HInstruction* instruction = it.Current();
44       if (instruction->IsInBlock()) {
45         instruction->Accept(this);
46       }
47     }
48   }
49 
50   void VisitAnd(HAnd * instruction) override;
51   void VisitXor(HXor* instruction) override;
52 
53  private:
54   CodeGeneratorX86* codegen_;
55   OptimizingCompilerStats* stats_;
56 };
57 
58 
VisitAnd(HAnd * instruction)59 void InstructionSimplifierX86Visitor::VisitAnd(HAnd* instruction) {
60   if (TryCombineAndNot(instruction)) {
61     RecordSimplification();
62   } else if (instruction->GetResultType() == DataType::Type::kInt32) {
63     if (TryGenerateResetLeastSetBit(instruction)) {
64       RecordSimplification();
65     }
66   }
67 }
68 
VisitXor(HXor * instruction)69 void InstructionSimplifierX86Visitor::VisitXor(HXor* instruction) {
70   if (instruction->GetResultType() == DataType::Type::kInt32) {
71     if (TryGenerateMaskUptoLeastSetBit(instruction)) {
72       RecordSimplification();
73     }
74   }
75 }
76 
Run()77 bool InstructionSimplifierX86::Run() {
78   InstructionSimplifierX86Visitor visitor(graph_, codegen_, stats_);
79   if (visitor.HasAVX2()) {
80     visitor.VisitReversePostOrder();
81     return true;
82   }
83   return false;
84 }
85 
86 }  // namespace x86
87 }  // namespace art
88 
89