OLD | NEW |
1 //===-- X86FastISel.cpp - X86 FastISel implementation ---------------------===// | 1 //===-- X86FastISel.cpp - X86 FastISel implementation ---------------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
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 defines the X86-specific support for the FastISel class. Much | 10 // This file defines the X86-specific support for the FastISel class. Much |
(...skipping 1550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1561 Flags.setByValAlign(FrameAlign); | 1561 Flags.setByValAlign(FrameAlign); |
1562 if (!IsMemcpySmall(FrameSize)) | 1562 if (!IsMemcpySmall(FrameSize)) |
1563 return false; | 1563 return false; |
1564 } | 1564 } |
1565 | 1565 |
1566 if (CS.paramHasAttr(AttrInd, Attribute::InReg)) | 1566 if (CS.paramHasAttr(AttrInd, Attribute::InReg)) |
1567 Flags.setInReg(); | 1567 Flags.setInReg(); |
1568 if (CS.paramHasAttr(AttrInd, Attribute::Nest)) | 1568 if (CS.paramHasAttr(AttrInd, Attribute::Nest)) |
1569 Flags.setNest(); | 1569 Flags.setNest(); |
1570 | 1570 |
1571 // If this is an i1/i8/i16 argument, promote to i32 to avoid an extra | 1571 unsigned ArgReg; |
1572 // instruction. This is safe because it is common to all fastisel supported | 1572 MVT ArgVT; |
1573 // calling conventions on x86. | |
1574 if (ConstantInt *CI = dyn_cast<ConstantInt>(ArgVal)) { | 1573 if (ConstantInt *CI = dyn_cast<ConstantInt>(ArgVal)) { |
| 1574 // If this is an i1/i8/i16 argument, promote to i32 to avoid an extra |
| 1575 // instruction. This is safe because it is common to all fastisel |
| 1576 // supported calling conventions on x86. |
1575 if (CI->getBitWidth() == 1 || CI->getBitWidth() == 8 || | 1577 if (CI->getBitWidth() == 1 || CI->getBitWidth() == 8 || |
1576 CI->getBitWidth() == 16) { | 1578 CI->getBitWidth() == 16) { |
1577 if (Flags.isSExt()) | 1579 if (Flags.isSExt()) |
1578 ArgVal = ConstantExpr::getSExt(CI,Type::getInt32Ty(CI->getContext())); | 1580 ArgVal = ConstantExpr::getSExt(CI,Type::getInt32Ty(CI->getContext())); |
1579 else | 1581 else |
1580 ArgVal = ConstantExpr::getZExt(CI,Type::getInt32Ty(CI->getContext())); | 1582 ArgVal = ConstantExpr::getZExt(CI,Type::getInt32Ty(CI->getContext())); |
1581 } | 1583 } |
1582 } | |
1583 | 1584 |
1584 unsigned ArgReg; | 1585 // Emit immediate arguments for the call locally to avoid spilling. |
1585 | 1586 if (!isTypeLegal(ArgVal->getType(), ArgVT)) return false; |
| 1587 uint64_t val; |
| 1588 if (Flags.isSExt()) |
| 1589 val = CI->getSExtValue(); |
| 1590 else |
| 1591 val = CI->getZExtValue(); |
| 1592 ArgReg = FastEmit_i(ArgVT, ArgVT, ISD::Constant, val); |
1586 // Passing bools around ends up doing a trunc to i1 and passing it. | 1593 // Passing bools around ends up doing a trunc to i1 and passing it. |
1587 // Codegen this as an argument + "and 1". | 1594 // Codegen this as an argument + "and 1". |
1588 if (ArgVal->getType()->isIntegerTy(1) && isa<TruncInst>(ArgVal) && | 1595 } else if (ArgVal->getType()->isIntegerTy(1) && isa<TruncInst>(ArgVal) && |
1589 cast<TruncInst>(ArgVal)->getParent() == I->getParent() && | 1596 cast<TruncInst>(ArgVal)->getParent() == I->getParent() && |
1590 ArgVal->hasOneUse()) { | 1597 ArgVal->hasOneUse()) { |
1591 ArgVal = cast<TruncInst>(ArgVal)->getOperand(0); | 1598 ArgVal = cast<TruncInst>(ArgVal)->getOperand(0); |
1592 ArgReg = getRegForValue(ArgVal); | 1599 ArgReg = getRegForValue(ArgVal); |
1593 if (ArgReg == 0) return false; | 1600 if (ArgReg == 0) return false; |
1594 | 1601 |
1595 MVT ArgVT; | |
1596 if (!isTypeLegal(ArgVal->getType(), ArgVT)) return false; | 1602 if (!isTypeLegal(ArgVal->getType(), ArgVT)) return false; |
1597 | 1603 |
1598 ArgReg = FastEmit_ri(ArgVT, ArgVT, ISD::AND, ArgReg, | 1604 ArgReg = FastEmit_ri(ArgVT, ArgVT, ISD::AND, ArgReg, |
1599 ArgVal->hasOneUse(), 1); | 1605 ArgVal->hasOneUse(), 1); |
1600 } else { | 1606 } else { |
1601 ArgReg = getRegForValue(ArgVal); | 1607 ArgReg = getRegForValue(ArgVal); |
1602 } | 1608 } |
1603 | 1609 |
1604 if (ArgReg == 0) return false; | 1610 if (ArgReg == 0) return false; |
1605 | 1611 |
1606 Type *ArgTy = ArgVal->getType(); | 1612 Type *ArgTy = ArgVal->getType(); |
1607 MVT ArgVT; | |
1608 if (!isTypeLegal(ArgTy, ArgVT)) | 1613 if (!isTypeLegal(ArgTy, ArgVT)) |
1609 return false; | 1614 return false; |
1610 if (ArgVT == MVT::x86mmx) | 1615 if (ArgVT == MVT::x86mmx) |
1611 return false; | 1616 return false; |
1612 unsigned OriginalAlignment = TD.getABITypeAlignment(ArgTy); | 1617 unsigned OriginalAlignment = TD.getABITypeAlignment(ArgTy); |
1613 Flags.setOrigAlign(OriginalAlignment); | 1618 Flags.setOrigAlign(OriginalAlignment); |
1614 | 1619 |
1615 Args.push_back(ArgReg); | 1620 Args.push_back(ArgReg); |
1616 ArgVals.push_back(ArgVal); | 1621 ArgVals.push_back(ArgVal); |
1617 ArgVTs.push_back(ArgVT); | 1622 ArgVTs.push_back(ArgVT); |
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2127 MI->eraseFromParent(); | 2132 MI->eraseFromParent(); |
2128 return true; | 2133 return true; |
2129 } | 2134 } |
2130 | 2135 |
2131 | 2136 |
2132 namespace llvm { | 2137 namespace llvm { |
2133 llvm::FastISel *X86::createFastISel(FunctionLoweringInfo &funcInfo) { | 2138 llvm::FastISel *X86::createFastISel(FunctionLoweringInfo &funcInfo) { |
2134 return new X86FastISel(funcInfo); | 2139 return new X86FastISel(funcInfo); |
2135 } | 2140 } |
2136 } | 2141 } |
OLD | NEW |