OLD | NEW |
---|---|
1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// | 1 //===- subzero/src/IceTargetLoweringX86BaseImpl.h - x86 lowering -*- C++ -*-==// |
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 /// \file | 10 /// \file |
(...skipping 5252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5263 // Base is Base=Var+Const || Base is Base=Const+Var ==> | 5263 // Base is Base=Var+Const || Base is Base=Const+Var ==> |
5264 // set Base=Var, Offset+=Const | 5264 // set Base=Var, Offset+=Const |
5265 // Base is Base=Var-Const ==> | 5265 // Base is Base=Var-Const ==> |
5266 // set Base=Var, Offset-=Const | 5266 // set Base=Var, Offset-=Const |
5267 // Index is Index=Var+Const ==> | 5267 // Index is Index=Var+Const ==> |
5268 // set Index=Var, Offset+=(Const<<Shift) | 5268 // set Index=Var, Offset+=(Const<<Shift) |
5269 // Index is Index=Const+Var ==> | 5269 // Index is Index=Const+Var ==> |
5270 // set Index=Var, Offset+=(Const<<Shift) | 5270 // set Index=Var, Offset+=(Const<<Shift) |
5271 // Index is Index=Var-Const ==> | 5271 // Index is Index=Var-Const ==> |
5272 // set Index=Var, Offset-=(Const<<Shift) | 5272 // set Index=Var, Offset-=(Const<<Shift) |
5273 // Treat Index=Var Or Const as Index=Var + Const | |
5274 // when Var = Var' << N and log2(Const) <= N | |
5275 // or when Var = (2^M) * (2^N) and log2(Const) <= (M+N) | |
5273 | 5276 |
5274 if (*IndexOrBase == nullptr) { | 5277 if (*IndexOrBase == nullptr) { |
5275 return nullptr; | 5278 return nullptr; |
5276 } | 5279 } |
5277 const Inst *Definition = VMetadata->getSingleDefinition(*IndexOrBase); | 5280 const Inst *Definition = VMetadata->getSingleDefinition(*IndexOrBase); |
5278 if (Definition == nullptr) { | 5281 if (Definition == nullptr) { |
5279 return nullptr; | 5282 return nullptr; |
5280 } | 5283 } |
5281 assert(!VMetadata->isMultiDef(*IndexOrBase)); | 5284 assert(!VMetadata->isMultiDef(*IndexOrBase)); |
5282 if (auto *ArithInst = llvm::dyn_cast<const InstArithmetic>(Definition)) { | 5285 if (auto *ArithInst = llvm::dyn_cast<const InstArithmetic>(Definition)) { |
5283 if (ArithInst->getOp() != InstArithmetic::Add && | 5286 if (ArithInst->getOp() != InstArithmetic::Add && |
5284 ArithInst->getOp() != InstArithmetic::Sub) | 5287 ArithInst->getOp() != InstArithmetic::Sub && |
5288 ArithInst->getOp() != InstArithmetic::Or) | |
Jim Stichnoth
2016/06/22 20:01:14
Once we're up to testing 3 values, I think this sh
manasijm
2016/06/27 18:04:18
Done.
| |
5285 return nullptr; | 5289 return nullptr; |
5286 bool IsAdd = ArithInst->getOp() == InstArithmetic::Add; | 5290 |
5287 Operand *Src0 = ArithInst->getSrc(0); | 5291 Operand *Src0 = ArithInst->getSrc(0); |
5288 Operand *Src1 = ArithInst->getSrc(1); | 5292 Operand *Src1 = ArithInst->getSrc(1); |
5289 auto *Var0 = llvm::dyn_cast<Variable>(Src0); | 5293 auto *Var0 = llvm::dyn_cast<Variable>(Src0); |
5290 auto *Var1 = llvm::dyn_cast<Variable>(Src1); | 5294 auto *Var1 = llvm::dyn_cast<Variable>(Src1); |
5291 auto *Const0 = llvm::dyn_cast<ConstantInteger32>(Src0); | 5295 auto *Const0 = llvm::dyn_cast<ConstantInteger32>(Src0); |
5292 auto *Const1 = llvm::dyn_cast<ConstantInteger32>(Src1); | 5296 auto *Const1 = llvm::dyn_cast<ConstantInteger32>(Src1); |
5293 auto *Reloc0 = llvm::dyn_cast<ConstantRelocatable>(Src0); | 5297 auto *Reloc0 = llvm::dyn_cast<ConstantRelocatable>(Src0); |
5294 auto *Reloc1 = llvm::dyn_cast<ConstantRelocatable>(Src1); | 5298 auto *Reloc1 = llvm::dyn_cast<ConstantRelocatable>(Src1); |
5299 | |
5300 bool IsAdd = false; | |
5301 if (ArithInst->getOp() == InstArithmetic::Or) { | |
5302 Variable *Var = nullptr; | |
5303 ConstantInteger32 *Const = nullptr; | |
5304 if (Var0 && Const1) { | |
5305 Var = Var0; | |
5306 Const = Const1; | |
5307 } else if (Const0 && Var1) { | |
5308 Var = Var1; | |
5309 Const = Const0; | |
5310 } else | |
5311 return nullptr; | |
5312 | |
5313 auto *VarDef = | |
5314 llvm::dyn_cast<InstArithmetic>(VMetadata->getSingleDefinition(Var)); | |
5315 if (VarDef == nullptr) | |
5316 return nullptr; | |
5317 | |
5318 auto uintLog2 = [](uint32_t x) { | |
Jim Stichnoth
2016/06/22 20:01:13
Can you just use llvm::Log2_32() or similar?
See
manasijm
2016/06/27 18:04:18
Done.
| |
5319 uint8_t result = 0; | |
5320 if (x > 0) do {result++;} while (x >>= 1); | |
5321 return result; | |
5322 }; | |
5323 | |
5324 SizeT numZeroes = 0; | |
Jim Stichnoth
2016/06/22 20:01:13
NumZeroes
manasijm
2016/06/27 18:04:18
Done.
| |
5325 if (VarDef->getOp() == InstArithmetic::Shl) { | |
5326 if (auto ConstInt = | |
Jim Stichnoth
2016/06/22 20:01:13
auto *
manasijm
2016/06/27 18:04:18
Done.
| |
5327 llvm::dyn_cast<ConstantInteger32>(VarDef->getSrc(1))) { | |
5328 numZeroes = ConstInt->getValue(); | |
5329 } | |
5330 } else if (VarDef->getOp() == InstArithmetic::Mul) { | |
5331 ConstantInteger32 *MultConst = nullptr; | |
Jim Stichnoth
2016/06/22 20:01:13
Combine this and the next line.
manasijm
2016/06/27 18:04:18
Done.
| |
5332 MultConst = llvm::dyn_cast<ConstantInteger32>(VarDef->getSrc(0)); | |
5333 if (llvm::isPowerOf2_32(MultConst->getValue())) { | |
5334 numZeroes += uintLog2(MultConst->getValue()); | |
5335 } | |
5336 MultConst = llvm::dyn_cast<ConstantInteger32>(VarDef->getSrc(1)); | |
5337 if (llvm::isPowerOf2_32(MultConst->getValue())) { | |
5338 numZeroes += uintLog2(MultConst->getValue()); | |
5339 } | |
5340 } | |
5341 SizeT LogValue = uintLog2(Const->getValue()); | |
5342 if (LogValue == 0 || LogValue > numZeroes) | |
5343 return nullptr; | |
5344 | |
5345 IsAdd = true; // treat it as an add if the above conditions hold | |
5346 } else { | |
5347 IsAdd = ArithInst->getOp() == InstArithmetic::Add; | |
5348 } | |
5349 | |
5295 Variable *NewIndexOrBase = nullptr; | 5350 Variable *NewIndexOrBase = nullptr; |
5296 int32_t NewOffset = 0; | 5351 int32_t NewOffset = 0; |
5297 ConstantRelocatable *NewRelocatable = *Relocatable; | 5352 ConstantRelocatable *NewRelocatable = *Relocatable; |
5298 if (Var0 && Var1) | 5353 if (Var0 && Var1) |
5299 // TODO(sehr): merge base/index splitting into here. | 5354 // TODO(sehr): merge base/index splitting into here. |
5300 return nullptr; | 5355 return nullptr; |
5301 if (!IsAdd && Var1) | 5356 if (!IsAdd && Var1) |
5302 return nullptr; | 5357 return nullptr; |
5303 if (Var0) | 5358 if (Var0) |
5304 NewIndexOrBase = Var0; | 5359 NewIndexOrBase = Var0; |
(...skipping 19 matching lines...) Expand all Loading... | |
5324 NewOffset += MoreOffset; | 5379 NewOffset += MoreOffset; |
5325 } | 5380 } |
5326 if (Const1) { | 5381 if (Const1) { |
5327 const int32_t MoreOffset = | 5382 const int32_t MoreOffset = |
5328 IsAdd ? Const1->getValue() : -Const1->getValue(); | 5383 IsAdd ? Const1->getValue() : -Const1->getValue(); |
5329 if (Utils::WouldOverflowAdd(*Offset + NewOffset, MoreOffset)) | 5384 if (Utils::WouldOverflowAdd(*Offset + NewOffset, MoreOffset)) |
5330 return nullptr; | 5385 return nullptr; |
5331 NewOffset += MoreOffset; | 5386 NewOffset += MoreOffset; |
5332 } | 5387 } |
5333 if (Utils::WouldOverflowAdd(*Offset, NewOffset << Shift)) | 5388 if (Utils::WouldOverflowAdd(*Offset, NewOffset << Shift)) |
5334 return nullptr; | 5389 return nullptr; |
5335 *IndexOrBase = NewIndexOrBase; | 5390 *IndexOrBase = NewIndexOrBase; |
5336 *Offset += (NewOffset << Shift); | 5391 *Offset += (NewOffset << Shift); |
5337 // Shift is always zero if this is called with the base | 5392 // Shift is always zero if this is called with the base |
5338 *Relocatable = NewRelocatable; | 5393 *Relocatable = NewRelocatable; |
5339 return Definition; | 5394 return Definition; |
5340 } | 5395 } |
5341 return nullptr; | 5396 return nullptr; |
5342 } | 5397 } |
5343 | 5398 |
5344 template <typename TypeTraits> | 5399 template <typename TypeTraits> |
(...skipping 2629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7974 emitGlobal(*Var, SectionSuffix); | 8029 emitGlobal(*Var, SectionSuffix); |
7975 } | 8030 } |
7976 } | 8031 } |
7977 } break; | 8032 } break; |
7978 } | 8033 } |
7979 } | 8034 } |
7980 } // end of namespace X86NAMESPACE | 8035 } // end of namespace X86NAMESPACE |
7981 } // end of namespace Ice | 8036 } // end of namespace Ice |
7982 | 8037 |
7983 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H | 8038 #endif // SUBZERO_SRC_ICETARGETLOWERINGX86BASEIMPL_H |
OLD | NEW |