comparison gen/toir.cpp @ 1225:837f48560863

No need for temporary alloca's here, use a phi node instead.
author Frits van Bommel <fvbommel wxs.nl>
date Sun, 19 Apr 2009 19:28:10 +0200
parents 50dc0db06238
children 01909bd1132c
comparison
equal deleted inserted replaced
1224:919fafcc505c 1225:837f48560863
1826 DValue* AndAndExp::toElem(IRState* p) 1826 DValue* AndAndExp::toElem(IRState* p)
1827 { 1827 {
1828 Logger::print("AndAndExp::toElem: %s @ %s\n", toChars(), type->toChars()); 1828 Logger::print("AndAndExp::toElem: %s @ %s\n", toChars(), type->toChars());
1829 LOG_SCOPE; 1829 LOG_SCOPE;
1830 1830
1831 // allocate a temporary for the final result. failed to come up with a better way :/
1832 LLValue* resval = 0;
1833 resval = DtoAlloca(LLType::Int1Ty,"andandtmp");
1834
1835 DValue* u = e1->toElem(p); 1831 DValue* u = e1->toElem(p);
1836 1832
1837 llvm::BasicBlock* oldend = p->scopeend(); 1833 llvm::BasicBlock* oldend = p->scopeend();
1838 llvm::BasicBlock* andand = llvm::BasicBlock::Create("andand", gIR->topfunc(), oldend); 1834 llvm::BasicBlock* andand = llvm::BasicBlock::Create("andand", gIR->topfunc(), oldend);
1839 llvm::BasicBlock* andandend = llvm::BasicBlock::Create("andandend", gIR->topfunc(), oldend); 1835 llvm::BasicBlock* andandend = llvm::BasicBlock::Create("andandend", gIR->topfunc(), oldend);
1840 1836
1841 LLValue* ubool = DtoCast(loc, u, Type::tbool)->getRVal(); 1837 LLValue* ubool = DtoCast(loc, u, Type::tbool)->getRVal();
1842 DtoStore(ubool,resval); 1838
1839 llvm::BasicBlock* oldblock = p->scopebb();
1843 llvm::BranchInst::Create(andand,andandend,ubool,p->scopebb()); 1840 llvm::BranchInst::Create(andand,andandend,ubool,p->scopebb());
1844 1841
1845 p->scope() = IRScope(andand, andandend); 1842 p->scope() = IRScope(andand, andandend);
1846 DValue* v = e2->toElem(p); 1843 DValue* v = e2->toElem(p);
1847 1844
1845 LLValue* vbool = 0;
1848 if (!v->isFunc() && v->getType() != Type::tvoid) 1846 if (!v->isFunc() && v->getType() != Type::tvoid)
1849 { 1847 {
1850 LLValue* vbool = DtoCast(loc, v, Type::tbool)->getRVal(); 1848 vbool = DtoCast(loc, v, Type::tbool)->getRVal();
1851 LLValue* uandvbool = llvm::BinaryOperator::Create(llvm::BinaryOperator::And, ubool, vbool,"tmp",p->scopebb()); 1849 }
1852 DtoStore(uandvbool,resval); 1850
1853 } 1851 llvm::BasicBlock* newblock = p->scopebb();
1854
1855 llvm::BranchInst::Create(andandend,p->scopebb()); 1852 llvm::BranchInst::Create(andandend,p->scopebb());
1856 p->scope() = IRScope(andandend, oldend); 1853 p->scope() = IRScope(andandend, oldend);
1857 1854
1858 resval = DtoLoad(resval); 1855 LLValue* resval = 0;
1856 if (ubool == vbool || !vbool) {
1857 // No need to create a PHI node.
1858 resval = ubool;
1859 } else {
1860 llvm::PHINode* phi = p->ir->CreatePHI(LLType::Int1Ty, "andandval");
1861 // If we jumped over evaluation of the right-hand side,
1862 // the result is false. Otherwise it's the value of the right-hand side.
1863 phi->addIncoming(LLConstantInt::getFalse(), oldblock);
1864 phi->addIncoming(vbool, newblock);
1865 resval = phi;
1866 }
1867
1859 return new DImValue(type, resval); 1868 return new DImValue(type, resval);
1860 } 1869 }
1861 1870
1862 ////////////////////////////////////////////////////////////////////////////////////////// 1871 //////////////////////////////////////////////////////////////////////////////////////////
1863 1872
1864 DValue* OrOrExp::toElem(IRState* p) 1873 DValue* OrOrExp::toElem(IRState* p)
1865 { 1874 {
1866 Logger::print("OrOrExp::toElem: %s @ %s\n", toChars(), type->toChars()); 1875 Logger::print("OrOrExp::toElem: %s @ %s\n", toChars(), type->toChars());
1867 LOG_SCOPE; 1876 LOG_SCOPE;
1868
1869 // allocate a temporary for the final result. failed to come up with a better way :/
1870 LLValue* resval = 0;
1871 resval = DtoAlloca(LLType::Int1Ty,"orortmp");
1872 1877
1873 DValue* u = e1->toElem(p); 1878 DValue* u = e1->toElem(p);
1874 1879
1875 llvm::BasicBlock* oldend = p->scopeend(); 1880 llvm::BasicBlock* oldend = p->scopeend();
1876 llvm::BasicBlock* oror = llvm::BasicBlock::Create("oror", gIR->topfunc(), oldend); 1881 llvm::BasicBlock* oror = llvm::BasicBlock::Create("oror", gIR->topfunc(), oldend);
1877 llvm::BasicBlock* ororend = llvm::BasicBlock::Create("ororend", gIR->topfunc(), oldend); 1882 llvm::BasicBlock* ororend = llvm::BasicBlock::Create("ororend", gIR->topfunc(), oldend);
1878 1883
1879 LLValue* ubool = DtoCast(loc, u, Type::tbool)->getRVal(); 1884 LLValue* ubool = DtoCast(loc, u, Type::tbool)->getRVal();
1880 DtoStore(ubool,resval); 1885
1886 llvm::BasicBlock* oldblock = p->scopebb();
1881 llvm::BranchInst::Create(ororend,oror,ubool,p->scopebb()); 1887 llvm::BranchInst::Create(ororend,oror,ubool,p->scopebb());
1882 1888
1883 p->scope() = IRScope(oror, ororend); 1889 p->scope() = IRScope(oror, ororend);
1884 DValue* v = e2->toElem(p); 1890 DValue* v = e2->toElem(p);
1885 1891
1892 LLValue* vbool = 0;
1886 if (!v->isFunc() && v->getType() != Type::tvoid) 1893 if (!v->isFunc() && v->getType() != Type::tvoid)
1887 { 1894 {
1888 LLValue* vbool = DtoCast(loc, v, Type::tbool)->getRVal(); 1895 vbool = DtoCast(loc, v, Type::tbool)->getRVal();
1889 DtoStore(vbool,resval); 1896 }
1890 } 1897
1891 1898 llvm::BasicBlock* newblock = p->scopebb();
1892 llvm::BranchInst::Create(ororend,p->scopebb()); 1899 llvm::BranchInst::Create(ororend,p->scopebb());
1893 p->scope() = IRScope(ororend, oldend); 1900 p->scope() = IRScope(ororend, oldend);
1894 1901
1895 resval = DtoLoad(resval); 1902 LLValue* resval = 0;
1903 if (ubool == vbool || !vbool) {
1904 // No need to create a PHI node.
1905 resval = ubool;
1906 } else {
1907 llvm::PHINode* phi = p->ir->CreatePHI(LLType::Int1Ty, "ororval");
1908 // If we jumped over evaluation of the right-hand side,
1909 // the result is true. Otherwise, it's the value of the right-hand side.
1910 phi->addIncoming(LLConstantInt::getTrue(), oldblock);
1911 phi->addIncoming(vbool, newblock);
1912 resval = phi;
1913 }
1914
1896 return new DImValue(type, resval); 1915 return new DImValue(type, resval);
1897 } 1916 }
1898 1917
1899 ////////////////////////////////////////////////////////////////////////////////////////// 1918 //////////////////////////////////////////////////////////////////////////////////////////
1900 1919