Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 1152783006: Subzero: Fold the load instruction into the next cast instruction. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Code review changes Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests_lit/llvm2ice_tests/8bit.pnacl.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file implements the TargetLoweringX8632 class, which 10 // This file implements the TargetLoweringX8632 class, which
(...skipping 865 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 // register) or already has one (if passed on the stack). 876 // register) or already has one (if passed on the stack).
877 if (Var->getIsArg()) 877 if (Var->getIsArg())
878 continue; 878 continue;
879 // An unreferenced variable doesn't need a stack slot. 879 // An unreferenced variable doesn't need a stack slot.
880 if (!IsVarReferenced[Var->getIndex()]) 880 if (!IsVarReferenced[Var->getIndex()])
881 continue; 881 continue;
882 // A spill slot linked to a variable with a stack slot should reuse 882 // A spill slot linked to a variable with a stack slot should reuse
883 // that stack slot. 883 // that stack slot.
884 if (SpillVariable *SpillVar = llvm::dyn_cast<SpillVariable>(Var)) { 884 if (SpillVariable *SpillVar = llvm::dyn_cast<SpillVariable>(Var)) {
885 assert(Var->getWeight().isZero()); 885 assert(Var->getWeight().isZero());
886 if (!SpillVar->getLinkedTo()->hasReg()) { 886 if (SpillVar->getLinkedTo() && !SpillVar->getLinkedTo()->hasReg()) {
887 VariablesLinkedToSpillSlots.push_back(Var); 887 VariablesLinkedToSpillSlots.push_back(Var);
888 continue; 888 continue;
889 } 889 }
890 } 890 }
891 SpilledVariables.push_back(Var); 891 SpilledVariables.push_back(Var);
892 } 892 }
893 893
894 SortedSpilledVariables.reserve(SpilledVariables.size()); 894 SortedSpilledVariables.reserve(SpilledVariables.size());
895 sortByAlignment(SortedSpilledVariables, SpilledVariables); 895 sortByAlignment(SortedSpilledVariables, SpilledVariables);
896 for (Variable *Var : SortedSpilledVariables) { 896 for (Variable *Var : SortedSpilledVariables) {
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 Hi->setName(Func, Var->getName(Func) + "__hi"); 1153 Hi->setName(Func, Var->getName(Func) + "__hi");
1154 } 1154 }
1155 Var->setLoHi(Lo, Hi); 1155 Var->setLoHi(Lo, Hi);
1156 if (Var->getIsArg()) { 1156 if (Var->getIsArg()) {
1157 Lo->setIsArg(); 1157 Lo->setIsArg();
1158 Hi->setIsArg(); 1158 Hi->setIsArg();
1159 } 1159 }
1160 } 1160 }
1161 1161
1162 Operand *TargetX8632::loOperand(Operand *Operand) { 1162 Operand *TargetX8632::loOperand(Operand *Operand) {
1163 assert(Operand->getType() == IceType_i64); 1163 assert(Operand->getType() == IceType_i64 ||
1164 if (Operand->getType() != IceType_i64) 1164 Operand->getType() == IceType_f64);
1165 if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64)
1165 return Operand; 1166 return Operand;
1166 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { 1167 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) {
1167 split64(Var); 1168 split64(Var);
1168 return Var->getLo(); 1169 return Var->getLo();
1169 } 1170 }
1170 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { 1171 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
1171 return Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue())); 1172 return Ctx->getConstantInt32(static_cast<uint32_t>(Const->getValue()));
1172 } 1173 }
1173 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { 1174 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) {
1174 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(), 1175 return OperandX8632Mem::create(Func, IceType_i32, Mem->getBase(),
1175 Mem->getOffset(), Mem->getIndex(), 1176 Mem->getOffset(), Mem->getIndex(),
1176 Mem->getShift(), Mem->getSegmentRegister()); 1177 Mem->getShift(), Mem->getSegmentRegister());
1177 } 1178 }
1178 llvm_unreachable("Unsupported operand type"); 1179 llvm_unreachable("Unsupported operand type");
1179 return nullptr; 1180 return nullptr;
1180 } 1181 }
1181 1182
1182 Operand *TargetX8632::hiOperand(Operand *Operand) { 1183 Operand *TargetX8632::hiOperand(Operand *Operand) {
1183 assert(Operand->getType() == IceType_i64); 1184 assert(Operand->getType() == IceType_i64 ||
1184 if (Operand->getType() != IceType_i64) 1185 Operand->getType() == IceType_f64);
1186 if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64)
1185 return Operand; 1187 return Operand;
1186 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) { 1188 if (Variable *Var = llvm::dyn_cast<Variable>(Operand)) {
1187 split64(Var); 1189 split64(Var);
1188 return Var->getHi(); 1190 return Var->getHi();
1189 } 1191 }
1190 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) { 1192 if (ConstantInteger64 *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
1191 return Ctx->getConstantInt32( 1193 return Ctx->getConstantInt32(
1192 static_cast<uint32_t>(Const->getValue() >> 32)); 1194 static_cast<uint32_t>(Const->getValue() >> 32));
1193 } 1195 }
1194 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) { 1196 if (OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand)) {
(...skipping 1261 matching lines...) Expand 10 before | Expand all | Expand 10 after
2456 } break; 2458 } break;
2457 case IceType_i64: { 2459 case IceType_i64: {
2458 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); 2460 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
2459 assert(Src0RM->getType() == IceType_f64); 2461 assert(Src0RM->getType() == IceType_f64);
2460 // a.i64 = bitcast b.f64 ==> 2462 // a.i64 = bitcast b.f64 ==>
2461 // s.f64 = spill b.f64 2463 // s.f64 = spill b.f64
2462 // t_lo.i32 = lo(s.f64) 2464 // t_lo.i32 = lo(s.f64)
2463 // a_lo.i32 = t_lo.i32 2465 // a_lo.i32 = t_lo.i32
2464 // t_hi.i32 = hi(s.f64) 2466 // t_hi.i32 = hi(s.f64)
2465 // a_hi.i32 = t_hi.i32 2467 // a_hi.i32 = t_hi.i32
2466 SpillVariable *SpillVar = Func->makeVariable<SpillVariable>(IceType_f64); 2468 Operand *SpillLo, *SpillHi;
2467 SpillVar->setLinkedTo(llvm::dyn_cast<Variable>(Src0RM)); 2469 if (auto *Src0Var = llvm::dyn_cast<Variable>(Src0RM)) {
2468 Variable *Spill = SpillVar; 2470 SpillVariable *SpillVar =
2469 Spill->setWeight(RegWeight::Zero); 2471 Func->makeVariable<SpillVariable>(IceType_f64);
2470 _movq(Spill, Src0RM); 2472 SpillVar->setLinkedTo(Src0Var);
2473 Variable *Spill = SpillVar;
2474 Spill->setWeight(RegWeight::Zero);
2475 _movq(Spill, Src0RM);
2476 SpillLo = VariableSplit::create(Func, Spill, VariableSplit::Low);
2477 SpillHi = VariableSplit::create(Func, Spill, VariableSplit::High);
2478 } else {
2479 SpillLo = loOperand(Src0RM);
2480 SpillHi = hiOperand(Src0RM);
2481 }
2471 2482
2472 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); 2483 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
2473 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); 2484 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
2474 Variable *T_Lo = makeReg(IceType_i32); 2485 Variable *T_Lo = makeReg(IceType_i32);
2475 Variable *T_Hi = makeReg(IceType_i32); 2486 Variable *T_Hi = makeReg(IceType_i32);
2476 VariableSplit *SpillLo =
2477 VariableSplit::create(Func, Spill, VariableSplit::Low);
2478 VariableSplit *SpillHi =
2479 VariableSplit::create(Func, Spill, VariableSplit::High);
2480 2487
2481 _mov(T_Lo, SpillLo); 2488 _mov(T_Lo, SpillLo);
2482 _mov(DestLo, T_Lo); 2489 _mov(DestLo, T_Lo);
2483 _mov(T_Hi, SpillHi); 2490 _mov(T_Hi, SpillHi);
2484 _mov(DestHi, T_Hi); 2491 _mov(DestHi, T_Hi);
2485 } break; 2492 } break;
2486 case IceType_f64: { 2493 case IceType_f64: {
2487 Src0 = legalize(Src0); 2494 Src0 = legalize(Src0);
2488 assert(Src0->getType() == IceType_i64); 2495 assert(Src0->getType() == IceType_i64);
2496 if (llvm::isa<OperandX8632Mem>(Src0)) {
2497 Variable *T = Func->makeVariable(Dest->getType());
2498 _movq(T, Src0);
2499 _movq(Dest, T);
2500 break;
2501 }
2489 // a.f64 = bitcast b.i64 ==> 2502 // a.f64 = bitcast b.i64 ==>
2490 // t_lo.i32 = b_lo.i32 2503 // t_lo.i32 = b_lo.i32
2491 // FakeDef(s.f64) 2504 // FakeDef(s.f64)
2492 // lo(s.f64) = t_lo.i32 2505 // lo(s.f64) = t_lo.i32
2493 // t_hi.i32 = b_hi.i32 2506 // t_hi.i32 = b_hi.i32
2494 // hi(s.f64) = t_hi.i32 2507 // hi(s.f64) = t_hi.i32
2495 // a.f64 = s.f64 2508 // a.f64 = s.f64
2496 SpillVariable *SpillVar = Func->makeVariable<SpillVariable>(IceType_f64); 2509 SpillVariable *SpillVar = Func->makeVariable<SpillVariable>(IceType_f64);
2497 SpillVar->setLinkedTo(Dest); 2510 SpillVar->setLinkedTo(Dest);
2498 Variable *Spill = SpillVar; 2511 Variable *Spill = SpillVar;
(...skipping 1449 matching lines...) Expand 10 before | Expand all | Expand 10 after
3948 // Index is Index=Var-Const ==> 3961 // Index is Index=Var-Const ==>
3949 // set Index=Var, Offset-=(Const<<Shift) 3962 // set Index=Var, Offset-=(Const<<Shift)
3950 3963
3951 // TODO: consider overflow issues with respect to Offset. 3964 // TODO: consider overflow issues with respect to Offset.
3952 // TODO: handle symbolic constants. 3965 // TODO: handle symbolic constants.
3953 } 3966 }
3954 } 3967 }
3955 3968
3956 } // anonymous namespace 3969 } // anonymous namespace
3957 3970
3958 void TargetX8632::lowerLoad(const InstLoad *Inst) { 3971 void TargetX8632::lowerLoad(const InstLoad *Load) {
3959 // A Load instruction can be treated the same as an Assign 3972 // A Load instruction can be treated the same as an Assign
3960 // instruction, after the source operand is transformed into an 3973 // instruction, after the source operand is transformed into an
3961 // OperandX8632Mem operand. Note that the address mode 3974 // OperandX8632Mem operand. Note that the address mode
3962 // optimization already creates an OperandX8632Mem operand, so it 3975 // optimization already creates an OperandX8632Mem operand, so it
3963 // doesn't need another level of transformation. 3976 // doesn't need another level of transformation.
3964 Type Ty = Inst->getDest()->getType(); 3977 Type Ty = Load->getDest()->getType();
3965 Operand *Src0 = FormMemoryOperand(Inst->getSourceAddress(), Ty); 3978 Operand *Src0 = FormMemoryOperand(Load->getSourceAddress(), Ty);
3966 3979
3967 // Fuse this load with a subsequent Arithmetic instruction in the 3980 // Fuse this load with a subsequent Arithmetic instruction in the
3968 // following situations: 3981 // following situations:
3969 // a=[mem]; c=b+a ==> c=b+[mem] if last use of a and a not in b 3982 // a=[mem]; c=b+a ==> c=b+[mem] if last use of a and a not in b
3970 // a=[mem]; c=a+b ==> c=b+[mem] if commutative and above is true 3983 // a=[mem]; c=a+b ==> c=b+[mem] if commutative and above is true
3971 // 3984 //
3985 // Fuse this load with a subsequent Cast instruction:
3986 // a=[mem]; b=cast(a) ==> b=cast([mem]) if last use of a
3987 //
3972 // TODO: Clean up and test thoroughly. 3988 // TODO: Clean up and test thoroughly.
3973 // (E.g., if there is an mfence-all make sure the load ends up on the 3989 // (E.g., if there is an mfence-all make sure the load ends up on the
3974 // same side of the fence). 3990 // same side of the fence).
3975 // 3991 //
3976 // TODO: Why limit to Arithmetic instructions? This could probably be 3992 // TODO: Why limit to Arithmetic instructions? This could probably be
3977 // applied to most any instruction type. Look at all source operands 3993 // applied to most any instruction type. Look at all source operands
3978 // in the following instruction, and if there is one instance of the 3994 // in the following instruction, and if there is one instance of the
3979 // load instruction's dest variable, and that instruction ends that 3995 // load instruction's dest variable, and that instruction ends that
3980 // variable's live range, then make the substitution. Deal with 3996 // variable's live range, then make the substitution. Deal with
3981 // commutativity optimization in the arithmetic instruction lowering. 3997 // commutativity optimization in the arithmetic instruction lowering.
3982 InstArithmetic *NewArith = nullptr; 3998 //
3983 if (InstArithmetic *Arith = 3999 // TODO(stichnot): Do load fusing as a separate pass. Run it before
3984 llvm::dyn_cast_or_null<InstArithmetic>(Context.getNextInst())) { 4000 // the bool folding pass. Modify Ice::Inst to allow src operands to
3985 Variable *DestLoad = Inst->getDest(); 4001 // be replaced, including updating Inst::LiveRangesEnded, to avoid
3986 Variable *Src0Arith = llvm::dyn_cast<Variable>(Arith->getSrc(0)); 4002 // having to manually mostly clone each instruction type.
3987 Variable *Src1Arith = llvm::dyn_cast<Variable>(Arith->getSrc(1)); 4003 Inst *NextInst = Context.getNextInst();
3988 if (Src1Arith == DestLoad && Arith->isLastUse(Src1Arith) && 4004 Variable *DestLoad = Load->getDest();
3989 DestLoad != Src0Arith) { 4005 if (NextInst && NextInst->isLastUse(DestLoad)) {
3990 NewArith = InstArithmetic::create(Func, Arith->getOp(), Arith->getDest(), 4006 if (auto *Arith = llvm::dyn_cast<InstArithmetic>(NextInst)) {
3991 Arith->getSrc(0), Src0); 4007 InstArithmetic *NewArith = nullptr;
3992 } else if (Src0Arith == DestLoad && Arith->isCommutative() && 4008 Variable *Src0Arith = llvm::dyn_cast<Variable>(Arith->getSrc(0));
3993 Arith->isLastUse(Src0Arith) && DestLoad != Src1Arith) { 4009 Variable *Src1Arith = llvm::dyn_cast<Variable>(Arith->getSrc(1));
3994 NewArith = InstArithmetic::create(Func, Arith->getOp(), Arith->getDest(), 4010 if (Src1Arith == DestLoad && DestLoad != Src0Arith) {
3995 Arith->getSrc(1), Src0); 4011 NewArith = InstArithmetic::create(
3996 } 4012 Func, Arith->getOp(), Arith->getDest(), Arith->getSrc(0), Src0);
3997 if (NewArith) { 4013 } else if (Src0Arith == DestLoad && Arith->isCommutative() &&
3998 Arith->setDeleted(); 4014 DestLoad != Src1Arith) {
3999 Context.advanceNext(); 4015 NewArith = InstArithmetic::create(
4000 lowerArithmetic(NewArith); 4016 Func, Arith->getOp(), Arith->getDest(), Arith->getSrc(1), Src0);
4001 return; 4017 }
4018 if (NewArith) {
4019 Arith->setDeleted();
4020 Context.advanceNext();
4021 lowerArithmetic(NewArith);
4022 return;
4023 }
4024 } else if (auto *Cast = llvm::dyn_cast<InstCast>(NextInst)) {
4025 Variable *Src0Cast = llvm::dyn_cast<Variable>(Cast->getSrc(0));
4026 if (Src0Cast == DestLoad) {
4027 InstCast *NewCast =
4028 InstCast::create(Func, Cast->getCastKind(), Cast->getDest(), Src0);
4029 Cast->setDeleted();
4030 Context.advanceNext();
4031 lowerCast(NewCast);
4032 return;
4033 }
4002 } 4034 }
4003 } 4035 }
4004 4036
4005 InstAssign *Assign = InstAssign::create(Func, Inst->getDest(), Src0); 4037 InstAssign *Assign = InstAssign::create(Func, DestLoad, Src0);
4006 lowerAssign(Assign); 4038 lowerAssign(Assign);
4007 } 4039 }
4008 4040
4009 void TargetX8632::doAddressOptLoad() { 4041 void TargetX8632::doAddressOptLoad() {
4010 Inst *Inst = Context.getCur(); 4042 Inst *Inst = Context.getCur();
4011 Variable *Dest = Inst->getDest(); 4043 Variable *Dest = Inst->getDest();
4012 Operand *Addr = Inst->getSrc(0); 4044 Operand *Addr = Inst->getSrc(0);
4013 Variable *Index = nullptr; 4045 Variable *Index = nullptr;
4014 uint16_t Shift = 0; 4046 uint16_t Shift = 0;
4015 int32_t Offset = 0; // TODO: make Constant 4047 int32_t Offset = 0; // TODO: make Constant
(...skipping 1016 matching lines...) Expand 10 before | Expand all | Expand 10 after
5032 case FT_Asm: 5064 case FT_Asm:
5033 case FT_Iasm: { 5065 case FT_Iasm: {
5034 OstreamLocker L(Ctx); 5066 OstreamLocker L(Ctx);
5035 emitConstantPool<PoolTypeConverter<float>>(Ctx); 5067 emitConstantPool<PoolTypeConverter<float>>(Ctx);
5036 emitConstantPool<PoolTypeConverter<double>>(Ctx); 5068 emitConstantPool<PoolTypeConverter<double>>(Ctx);
5037 } break; 5069 } break;
5038 } 5070 }
5039 } 5071 }
5040 5072
5041 } // end of namespace Ice 5073 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | tests_lit/llvm2ice_tests/8bit.pnacl.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698