Basic fast-isel of extractvalue. Not too helpful on its own, given the IR clang generates for cases like this, but it should become more useful soon.

llvm-svn: 131417
This commit is contained in:
Eli Friedman 2011-05-16 20:27:46 +00:00
parent 9c876bf937
commit 9ac944774f
3 changed files with 70 additions and 0 deletions

View File

@ -343,6 +343,8 @@ private:
bool SelectCast(const User *I, unsigned Opcode);
bool SelectExtractValue(const User *I);
/// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks.
/// Emit code to ensure constants are copied into registers when needed.
/// Remember the virtual registers that need to be added to the Machine PHI

View File

@ -44,6 +44,7 @@
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Operator.h"
#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/FastISel.h"
#include "llvm/CodeGen/FunctionLoweringInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@ -838,6 +839,44 @@ FastISel::SelectFNeg(const User *I) {
return true;
}
bool
FastISel::SelectExtractValue(const User *U) {
const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(U);
if (!U)
return false;
// Make sure we only try to handle extracts with a legal result.
EVT RealVT = TLI.getValueType(EVI->getType(), /*AllowUnknown=*/true);
if (!RealVT.isSimple())
return false;
MVT VT = RealVT.getSimpleVT();
if (!TLI.isTypeLegal(VT))
return false;
const Value *Op0 = EVI->getOperand(0);
const Type *AggTy = Op0->getType();
// Get the base result register.
unsigned ResultReg;
DenseMap<const Value *, unsigned>::iterator I = FuncInfo.ValueMap.find(Op0);
if (I != FuncInfo.ValueMap.end())
ResultReg = I->second;
else
ResultReg = FuncInfo.InitializeRegForValue(Op0);
// Get the actual result register, which is an offset from the base register.
unsigned VTIndex = ComputeLinearIndex(AggTy, EVI->idx_begin(), EVI->idx_end());
SmallVector<EVT, 4> AggValueVTs;
ComputeValueVTs(TLI, AggTy, AggValueVTs);
for (unsigned i = 0; i < VTIndex; i++)
ResultReg += TLI.getNumRegisters(FuncInfo.Fn->getContext(), AggValueVTs[i]);
UpdateValueMap(EVI, ResultReg);
return true;
}
bool
FastISel::SelectOperator(const User *I, unsigned Opcode) {
switch (Opcode) {
@ -942,6 +981,9 @@ FastISel::SelectOperator(const User *I, unsigned Opcode) {
return true;
}
case Instruction::ExtractValue:
return SelectExtractValue(I);
case Instruction::PHI:
llvm_unreachable("FastISel shouldn't visit PHI nodes!");

View File

@ -0,0 +1,26 @@
; RUN: llc < %s -mtriple x86_64-apple-darwin11 -O0 | FileCheck %s
%struct.x = type { i64, i64 }
declare %struct.x @f()
define void @test1(i64*) nounwind ssp {
%2 = tail call %struct.x @f() nounwind
%3 = extractvalue %struct.x %2, 0
%4 = add i64 %3, 10
store i64 %4, i64* %0
ret void
; CHECK: test1:
; CHECK: callq _f
; CHECK-NEXT: addq $10, %rax
}
define void @test2(i64*) nounwind ssp {
%2 = tail call %struct.x @f() nounwind
%3 = extractvalue %struct.x %2, 1
%4 = add i64 %3, 10
store i64 %4, i64* %0
ret void
; CHECK: test2:
; CHECK: callq _f
; CHECK-NEXT: addq $10, %rdx
}